This topic will be split into various parts, discussing different methods. Part 1 is a stupid solution, Part 2 and Part 3's solutions worked quite well for me.

Intro

First off, this article is not about revision or source control, but rather identifying the FPGA firmware build when it is configured onto a device.

Pretty much all of the projects I have worked on have included a micro-controller. There are some sort of communication interface between the processor and the FPGA. For the purpose of these articles this interface is a 32 bit data and 32 bit address bus (lw AXI). 

The FPGA firmware contains various memory mapped registers that allows the software running on the processor to configure certain features and read back status of certain events. During development the software and firmware are developed by different people. My process of development is developing a feature and supplying the software engineer with a firmware build to integrate and test in the software. While this is happening I start working on the next feature. This means the firmware builds that the software engineer uses always lags behind, so if he/she comes across a bug or feature not working as expected I need to be able to see what firmware build they are testing against.

 

Solution

A simple solution is to create a memory mapped register that stores a version number. A neat solution would have this number increment automatically with each build as I sometimes forget to increment this number, but I have not found a way to run pre-synthesis script in the Xilinx ISE toolsuite.

Creating a constant containing the version number in the top level design works really easy 

 

constant C_VERSION : std_logic_vector(31 downto 0) := x"00000023";

 

An easier way is to define a constant as a natural number and then use the conversion functions to convert it to a logic vector

 

constant C_INT_VERSION : natural := 35;
constant C_VERSION : std_logic_vector(31 downto 0) := std_logic_vector(to_unsigned( C_INT_VERSION, 32));

 

This is simple, yet affective. The problem with this method is that certain companies has an internal version structure. The structure was that, the number defined in this constant is divided by 100.0 to express the version, e.g. a value of 35 will equal to v0.35. Version 1.00 is the initial release version. The development versions are then from 0.01 to 0.99. However once version 1.00 is out there development does NOT continue from 1.01 to 1.99, instead it jumps back to 0.01 to 0.99 and the engineers should keep track of this. This forced me to come up with a different solutions. These are described in Part 2 and Part 3.