Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16613 Discussions

automatic firmware revision for VHDL

Altera_Forum
Honored Contributor II
1,631 Views

Dear Experts, 

i'd like to introduce to my design one register containing a firmware 

revision. Very probably the firmware revision would be a data when the 

VHDL code was checked out from the CVS repository where I store the 

project. 

 

The problem I encounter is how to translate the CVS last-commit data 

of the project currently checked out, and translate it into VHDL code 

to be a part of the project. 

 

Example: 

 

yesterday i committed at the end of day the whole project, thus when I 

check it out today and burn, one of the registers I export should 

contain yesterday's date as a firmware revision 

 

i check out the project corresponding to a date 2 weeks ago, the 

firmware register should contain a number corresponding to date at 

which the version of the project I have checked out was committed. 

 

This would allow very easily match the firmware and CVS source 

together..... 

 

any ideas how to do it? 

 

thanks 

david
0 Kudos
5 Replies
Altera_Forum
Honored Contributor II
571 Views

For subversion I did it with a pre flow tcl script. This scrit is run automatically before compilatio starts. You have to set a variable in the qsf file like this :  

 

set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:./VersionInfoGenerator/svn.tcl" 

 

In the script I generate a design file (verilog in my case) that contains some registers with the version number. I suspect that for cvs the same must be possible. 

 

See also : http://www.altera.com/support/examples/tcl/tcl-svn-revision.html (http://www.altera.com/support/examples/tcl/tcl-svn-revision.html

 

Stefaan
0 Kudos
Altera_Forum
Honored Contributor II
571 Views

I don't how to read in the CVS info, but the action should be basically possible through a Tcl script executed as PRE_FLOW_SCRIPT_FILE. How to define a pre-compilation script has been recently discussed in the forum, e. g. http://www.alteraforum.com/forum/showthread.php?t=1996 and is also documented in the quartus ii version 7.2 handbook volume 2, section 3. tcl scripting, automating script execution. 

 

Tcl is a full featured script interpreter includiing file-IO and text processing commands, so it should be able to e. g. write the intended information to a VHDL constant definition.
0 Kudos
Altera_Forum
Honored Contributor II
571 Views

Hi All, 

thanks for useful info. In fact I did something similar because I didn't know about PRE_FLOW_SCRIPT_FILE feature of quartus. I have built a small TCL script which generates entity having one output vector of 32 bits, which is fed by output of 'clock seconds' TCL command. However in order to run compilation I have used TCL script which does it for me, and not the PRE_FLOW_SCRIPT_FILE. Your solution is better because it keeps the current development flow intact. 

 

d.
0 Kudos
Altera_Forum
Honored Contributor II
571 Views

Dear All, 

i have managed to make a working solution for the version control using CVS. This info is for those who are interested in a similar thing. The source as well as ideas are compiled of many sources, including hints from this thread. 

 

So, short howto: 

 

1) when using CVS to store your project, store the POF (programmer object file) as well. We use POF file as an identification of the revision of the project. CVS does not have (imho) a revision number for module. POF file is a good choice because every time you make an update to source file, quartus generates unique POF for this vhdl-file-set. One can use SOF as well, but imho putting both SOF and POF into CVS does not bring any added value.  

 

2) setup CVS connection to your CVS server by using automatic SSH authentication (public/private keys) 

 

3) put this script into either project directory or somewhere where you store VHDL files. The system visibility is not necessary because you'll call it from quartus by relative calls anyways. Script is here: 

 

get_revision.tcl: 

====================================================== 

# !/usr/bin/tclsh # note: in order to be sure that code is fine, file_name should be a sram object file # or program object file. These must be of course imported to CVS! # Comments? Bug reports? email: david.belohrad@cern.ch package require cmdline proc get_cvs_revision { file_name } { global done # The maximum number of seconds to wait for the svn info # command to complete set timeout_seconds 30 # The svn info command with filename that is run set cmd "cvs log ${file_name}" # Attempt to get the version information. # If the command can't be run, return an error. # Otherwise set up a file event to process the command output. if { } { return -code error $input } else { fileevent $input readable # Set up a timeout so that the process can't hang if the # repository is down. set timeout ] # Don't continue until the revision number is found, # or the operation times out. Cancel the timeout anyway. vwait done after cancel $timeout } } proc get_revision_info { inp } { global done magic_number if { } { catch {close $inp} set done 1 } elseif { $done } { gets $inp line } else { gets $inp line # Use a regular expression to match the line with the # revision number. The revision number up to fourh number is # supported if { } { set record # for loop to get integer: set magic_number 0 set recordno 3 foreach pt $record { set mtemp ] # cannot be higher revision number because we would run out of ULONG type: if {$mtemp > 255} { set mtemp 255 } set con set magic_number set recordno } } } } proc create_entity { filename } { global magic_number # this script generates an entity with given revision number set fi puts $fi "library ieee;" puts $fi "use ieee.std_logic_1164.all;" puts $fi "use ieee.numeric_std.all;" puts $fi "entity fw_revision is" puts $fi "port (" puts $fi "\trevision : out std_logic_vector(31 downto 0));" puts $fi "end entity fw_revision;\n" puts $fi "architecture v1 of fw_revision is" puts $fi "begin -- architecture v1" puts $fi "\trevision <= STD_LOGIC_VECTOR(TO_UNSIGNED($magic_number,revision'length));" puts $fi "end architecture v1;" close $fi } # note: if this file is run via quartus_sh, we get additional parameters # on the command line. this is flowtype, project name and revision. # as project name is corresponding to the .pof file generated, we can # use this information to create our revision file: set file_name append file_name ".pof" set project_name set revision_name post_message "get_revision.tcl: Getting revision for $file_name..." # this filename is used to open the project, if not opened. The project # needs to be opened because we need to know about project working directory. if {} { if {} { project_open $project_name -revision } else { project_open $project_name -revision $revision_name } } else { post_message -type error "Project $project_name does not exist" exit } post_message "get_revision.tcl: project opened, project name: $project_name, revision: $revision_name" set done 0 set magic_number 0 if { } { post_message -type critical_warning "Couldn't run command to get revision number. $msg" } else { if { -1 == $done } { post_message -type critical_warning "Timeout getting revision number." } elseif { } { post_message -type critical_warning "Couldn't find revision number in output of cvs info $file_name." } else { post_message "Revision for $file_name is $magic_number (0x)" # create new entity in sources/fwrevision directory set prjfile append prjfile "sources/fwrevision" # we have full path, let's check whether it exists: file mkdir $prjfile # call procedure to make an entity: append prjfile "/fw_revision.vhd" puts "Creating $prjfile ..." create_entity $prjfile post_message "get_revision.tcl: done." } } # close project: if { project_close }  

 

4) what the script does: the script must be called from quartus environment, the calling 

parameters must be the same as of PRE_FLOW_SCRIPT_FILE, thus <flowtype> <projectname> <revisionname>. The script opens the project, creates a filename of the POF file corresponding to the project name, then calls CVS LOG command to find out the revisions of the POF file. By using regular expressions it extracts the 'HEAD' revision number. As CVS revision number is not a single number like in SVN, but it has at least one major and one minor release version (e.g. 1.32) we need to parse it somehow to get in VHDL decent information about version. The script supports the revision number up to 2 subbranches, thus maximum allowed revision number would be something like 1.32.2.3. Additional subbranches are lost. The revision number is converted to the unsigned long number of type 0xMMIIBBSS, where M=major number, I=minor number, B = branch, S = subbranch. If B and/or S are not used, zero is filled. Such LONG revision number is put into the entity called fw_revision. The entity exports single 32bit STD_LOGIC_VECTOR containing the value above. The entity is by default created in <projectdirectory>/sources/fwrevision/fw_revision.vhd. Note, that neither fwrevision directory nor fw_revision.vhd file must be imported into CVS. When you check out plain VHDL code, the directory and file inside must not exist.  

 

5) the entity generated looks like: 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity fw_revision is port ( revision : out std_logic_vector(31 downto 0)); end entity fw_revision; architecture v1 of fw_revision is begin -- architecture v1 revision <= STD_LOGIC_VECTOR(TO_UNSIGNED(16973824,revision'length)); end architecture v1;  

where the number 12973824 (0x01030000) corresponds to CVS revision 1.3 of POF file. 

 

6) in order to make it automatically called from within quartus you have to put following sentence 

into your QSF file: 

 

# automatic script run to get every time a revision: 

set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:../cfga_vhdl/get_revision.tcl"  

where ../cfga_vhdl is a relative path of the get_revision.tcl script with respect to the project directory 

 

 

------------- 

Hope this helps to someone else as well. 

 

d.
0 Kudos
Altera_Forum
Honored Contributor II
571 Views

Small bug repair: 

 

replace: 

set cmd "cvs log ${file_name}"  

by 

set cmd "cvs status ${file_name}"  

and line 

if { } {  

by 

if { } {  

 

Otherwise for branched code you will not get correct output.
0 Kudos
Reply