top of page

MicroZed Chronicles: Automatically Adding Build Version.

Last week we examined how we could work with Git and source control on our FPGA designs. Along with working with Git for source control, one additional aspect which is very important is the ability to include the latest git tag in the FPGA design such that it can be accessed by the developer during testing of the FPGA.

 

The ability to ensure a specific version of a FPGA is being used is critical when it comes to ensuring the latest design is loaded or which version is running when there are issues with the design.

 

In this blog we are going to examine how we can create a script which accesses the latest git tag and appends the information into a RTL file which can then be accessed over AXI lite. This block can then be implemented as part of the design either connected to a processor based solution or connected to our UART/SP/I2C to AXI interconnectivity.

 

As we mostly want to do this for our professional developments, which we tend to script I will be using Vivado in the TCL project mode flow for this blog.

 

This approach is very simple, we have a simple file which implements a AXI Lite register which supports read only. Within this file is a register which gets set by a TCL script, this TCL script interrogates the git repo and determines the short git commit ID and formats this to a 32 bit word.

 

This script can be included as part of out Vivado project rebuild script we use within the TCL Project mode flow. Using the project mode allows us to open the project in the GUI if we desire and make changes to the design also.

 

I have updated the design we used in our Vivado project last week to include the version ip block. The completed design looks as below.

The git script to interrogate the repository and determine the short git id can be seen below

 


# Function to get the current short commit ID from Git
proc get_short_git_commit_id {} {
    set git_command "git rev-parse --short HEAD"
    set result [catch {exec git rev-parse --short HEAD} commit_id]
    if {$result == 0} {
        return [format "%08s" $commit_id]
    } else {
        return "ERROR";  # Default or error code if git command fails
    }
}

# Function to insert or update a signal in the VHDL file
proc update_or_insert_signal {file_path commit_id} {
    # Read the content of the VHDL file
    set f [open $file_path r]
    set file_data [split [read $f] "\n"]
    close $f

    # Initialize a list to hold the new file content and a flag for insertion
    set new_file_data {}
    set found 0

    # Define the new signal line with the formatted Git commit
    set new_signal "signal version : std_logic_vector(31 downto 0) := x\"$commit_id\"; -- New version signal based on Git commit"

    # Check if the line already exists and needs updating
    foreach line $file_data {
        # Check if this line defines the 'version' signal
        if {[string match "*signal version : std_logic_vector(31 downto 0) := x*\"*" $line]} {
            # Append the updated signal definition
            lappend new_file_data $new_signal
            set found 1
        } else {
            lappend new_file_data $line
        }
    }

    # If the signal was not found and updated, add it to the end
    if {$found == 0} {
        lappend new_file_data $new_signal
    }

    # Write the modified content back to the VHDL file
    set f [open $file_path w]
    foreach line $new_file_data {
        puts $f $line
    }
    close $f

    puts "VHDL file has been updated or new signal has been added in $file_path"
}

# Main execution
set current_project [get_property DIRECTORY [current_project]]
cd $current_project
set vhdl_file_name "git_demo.srcs/sources_1/imports/new/version_reg.vhd"
set vhdl_file_path "$current_project/$vhdl_file_name"
set commit_id [get_short_git_commit_id]

# Check for error before proceeding
if {$commit_id == "ERROR"} {
    puts "Failed to retrieve Git commit ID."
} else {
    update_or_insert_signal $vhdl_file_path $commit_id
    puts "VHDL file updated with new register default value: $commit_id"
}

The output of the script is the version register file being updated to show the following.

There are a few things we need to change in the script such as the location of the version register RTL file before it is run.

 

We can then use the Vivado build script below to update the git version and build the bit stream. One thing we need to ensure the script does is that after the version RTL file is updated we update the IPs within the design, before running building the bitstream.  


open_project git_demo.xpr
source git_repo.tcl 
upgrade_ip [get_ips *]
reset_run synth_1
launch_runs synth_1
wait_on_run synth_1
launch_runs impl_1 -to_step write_bitstream
wait_on_run impl_1
puts "Implementation done!"

 

To test this once the bitstream is available we can build the design in Vivado and Vitis and use the ZynqMP to read the register value.

 

This can be accessed easily by writing simple code which reads the register value and outputs it to the terminal. We can also access the register over the memory view in Vitis.

 

To demonstrate this worked I ran the build script first on the original commit, the content of the register can be seen in the memory view below.

I then updated the repository but pushing the new scripts and files I had created and re ran the build script.

 

This time we can see the value reported is different.


Both of these align with the short git ids shown in smart git, which confirms the code is working properly.

Of course if you wanted this could be expanded to have several registers which contain further information such as time and date of build etc. Everything you need is in the repository here.


Workshops and Webinars


If you enjoyed the blog why not take a look at the free webinars, workshops and training courses we have created over the years. Highlights include



Boards

Get an Adiuvo development board



Embedded System Book   


Do you want to know more about designing embedded systems from scratch? Check out our book on creating embedded systems. This book will walk you through all the stages of requirements, architecture, component selection, schematics, layout, and FPGA / software design. We designed and manufactured the board at the heart of the book! The schematics and layout are available in Altium here   Learn more about the board (see previous blogs on Bring up, DDR validation, USB, Sensors) and view the schematics here.



Sponsored by AMD


Comments


bottom of page