# Tcl script to automatically generate the SDB synthesis descriptor. # # Must be added to your top-level Manifest.py like this: # # syn_post_project_cmd = "$(TCL_INTERPRETER) [this_tcl_script] " + # syn_tool + " $(PROJECT_FILE)" # # Notes: # # 1. $(TCL_INTERPRETER) and $(PROJECT_FILE) will be automatically # resolved inside the Makefile generated by hdlmake. # 2. syn_tool is a Manifest.py variable, it should already be in your # tol-level Manifest.py. # 3. [this_tcl_script] should be replaced by the full path to # this Tcl script. Relative paths should be with respect to # the location of the top-level Manifest.py. # 4. Mind the spaces inside the quotes, before and after syn_tool. # get current time set time_now [clock seconds] # set list of supported tools set supported_tools [list ise] # get synthesis tool from 1st command line argument set syn_tool [lindex $argv 0] # get project file from 2nd command-line argument set project_file [lindex $argv 1] # set file for all output set out_file synthesis_descriptor.vhd # short procedure for consistent reporting proc report {level message} { puts "$level:$::argv0 - $message" } # procedure to make sure a given string has a certain length, # necessary for embedding strings in SDB. If string is longer, it is # trimmed, if it is shorter it is padded (by default with spaces). # # For the curious: https://en.wikipedia.org/wiki/Procrustes proc str_procrustes {str limit {pad_char " "}} { set str_len [string length $str] if {[expr $str_len < $limit]} { set pad [string repeat $pad_char [expr $limit - $str_len]] return $str$pad } else { return [string range $str 0 [expr $limit - 1]] } } #------------------------------------------------------------------------------- # STEP 1/7: Check that the synthesis tool is supported #------------------------------------------------------------------------------- if {[lsearch -exact $supported_tools $syn_tool] == -1} { report ERROR "$syn_tool is not (yet) supported, exiting." exit -1 } #------------------------------------------------------------------------------- # STEP 2/7: Check that project file exists #------------------------------------------------------------------------------- if {![file exists $project_file]} { report ERROR "Missing file $project_file, exiting." exit -1 } #------------------------------------------------------------------------------- # STEP 3/7: Open project file #------------------------------------------------------------------------------- if {$syn_tool == "ise"} { xilinx::project open $project_file # dummy call to project get name to ger rid of annoying error # regarding list of boards for ISim xilinx::project get name } report INFO "Opened project $project_file." #------------------------------------------------------------------------------- # STEP 4/7: Get necessary info from synthesis tool and Git #------------------------------------------------------------------------------- if {$syn_tool == "ise"} { set inf_project [xilinx::project get name] # ISE does not provide a tcl command to get version. # Possible ways include parsing the project file (not backward compatible) # or Xilinx AR#35500. # For now we hard-code, since anyway ISE is end-of-life at version 14.7. set inf_tool_version [format "%08d" "147"] } set inf_tool_name [string toupper $syn_tool] set inf_commit_id [exec git log -1 --format=%H] set inf_date [clock format $time_now -format "%A, %B %d %Y"] set inf_date_ymd [clock format $time_now -format "%Y%m%d"] set inf_user [exec git config user.name] # next line could break if git remote is not called "origin" set inf_repo_url [exec git remote get-url origin] #------------------------------------------------------------------------------- # STEP 5/7: Generate the output file #------------------------------------------------------------------------------- set fp [open $out_file w] puts $fp [string repeat "-" 80] puts $fp "-- SDB meta information for $project_file." puts $fp "--" puts $fp "-- This file was automatically generated by $argv0 on:" puts $fp "-- $inf_date" puts $fp "--" puts $fp "-- $argv0 is part of OHWR general-cores:" puts $fp "-- https://www.ohwr.org/projects/general-cores/wiki" puts $fp "--" puts $fp "-- For more information on SDB meta information, see also:" puts $fp "-- https://www.ohwr.org/projects/sdb/wiki" puts $fp [string repeat "-" 80] puts $fp "" puts $fp "library ieee;" puts $fp "use ieee.std_logic_1164.all;" puts $fp "use work.wishbone_pkg.all;" puts $fp "" puts $fp "package synthesis_descriptor is" puts $fp "" puts $fp " constant c_sdb_synthesis_info : t_sdb_synthesis := (" puts $fp " syn_module_name => \"[str_procrustes $inf_project 16]\"," puts $fp " syn_commit_id => \"[str_procrustes $inf_commit_id 32]\"," puts $fp " syn_tool_name => \"[str_procrustes $inf_tool_name 8]\"," puts $fp " syn_tool_version => x\"$inf_tool_version\"," puts $fp " syn_date => x\"[str_procrustes $inf_date_ymd 8]\"," puts $fp " syn_username => \"[str_procrustes $inf_user 15]\");" puts $fp "" puts $fp " constant c_sdb_repo_url : t_sdb_repo_url := (" puts $fp " repo_url => \"[str_procrustes $inf_repo_url 63]\");" puts $fp "" puts $fp "end package synthesis_descriptor;" close $fp #------------------------------------------------------------------------------- # Step 6/7: Add the output file to the project #------------------------------------------------------------------------------- if {$syn_tool == "ise"} { xilinx::xfile add $out_file } report "INFO" "Added $out_file to $project_file." #------------------------------------------------------------------------------- # Step 7/7: Close project file #------------------------------------------------------------------------------- if {$syn_tool == "ise"} { xilinx::project close } report "INFO" "Closed project $project_file."