23 set tcl_path [
file normalize "[
file dirname [
info script]]/.."]
24 source $tcl_path/hog.tcl
28 if {[
info exists env(HOG_TCLLIB_PATH)]} {
29 lappend auto_path $env(HOG_TCLLIB_PATH)
31 puts "ERROR: To run Hog with Microsemi Libero SoC, you need to define the HOG_TCLLIB_PATH variable."
37 puts "I am running Libero"
40 if {[
catch {
package require struct::matrix} ERROR]} {
41 puts "$ERROR\n If you are running this script on tclsh, you can fix this by installing 'tcllib'"
49 set old_path [
file normalize "../../Projects/$project/$project.runs/synth_1"]
55 if {[
info exists env(HOG_EXTERNAL_PATH)]} {
56 set ext_path $env(HOG_EXTERNAL_PATH)
57 Msg Info "Found environment variable HOG_EXTERNAL_PATH, setting path for external files to $ext_path..."
65 set proj_file [get_property DIRECTORY [current_project]]
67 set proj_file [get_property parent.project_path [current_project]]
69 set proj_dir [
file normalize [
file dirname $proj_file]]
70 set proj_name [
file rootname [
file tail $proj_file]]
73 set proj_name [
lindex $quartus(args) 1]
76 set proj_file [
file normalize "$proj_dir/$proj_name.qpf"]
78 set hogQsysFileName [
file normalize "$proj_dir/.hog/.hogQsys.md5"]
79 if { [
file exists $hogQsysFileName] != 0} {
80 set hogQsysFile [open $hogQsysFileName r]
81 set hogQsysFileLines [
split [read $hogQsysFile] "\n"]
82 foreach line $hogQsysFileLines {
83 set fileEntry [
split $line "\t"]
84 set fileEntryName [
lindex $fileEntry 0]
85 if {$fileEntryName != ""} {
86 if {[
file exists $fileEntryName]} {
87 set newMd5Sum [
Md5Sum $fileEntryName]
88 set oldMd5Sum [
lindex $fileEntry 1]
89 if { $newMd5Sum != $oldMd5Sum } {
90 Msg Warning "The checksum for file $fileEntryName not equal to the one saved in $hogQsysFileName: new checksum $newMd5Sum, old checksum $oldMd5Sum. Please check the any changes in the file are correctly propagated to git!"
93 Msg Warning "File $fileEntryName not found... Will not check Md5Sum!"
100 set proj_dir [
file normalize [
file dirname "[project_data -dir]/../.."]]
101 set proj_name [
file tail $proj_dir]
102 set project $proj_name
105 set proj_file $old_path/[
file tail $old_path].xpr
106 set proj_dir [
file normalize [
file dirname $proj_file]]
107 set proj_name [
file rootname [
file tail $proj_file]]
108 Msg CriticalWarning "You seem to be running locally on tclsh, so this is a debug, the project file will be set to $proj_file and was derived from the path you launched this script from: $old_path. If you want this script to work properly in debug mode, please launch it from the top folder of one project, for example Repo/Projects/fpga1/ or Repo/Top/fpga1/"
112 set repo_path [
file normalize "$tcl_path/../.."]
118 set flavour [
string map {. ""} [
file extension $proj_name]]
119 if {$flavour != ""} {
120 if {[
string is integer $flavour]} {
121 Msg Info "Project $proj_name has flavour = $flavour, the generic variable FLAVOUR will be set to $flavour"
123 Msg Warning "Project name has a unexpected non numeric extension, flavour will be set to -1"
135 lassign [
GetRepoVersions [
file normalize $repo_path/Top/$group/$proj_name] $repo_path $ext_path] commit version hog_hash hog_ver top_hash top_ver libs hashes vers cons_ver cons_hash ext_names ext_hashes xml_hash xml_ver user_ip_repos user_ip_hashes user_ip_vers
139 set dst_dir [
file normalize "bin/$group/$proj_name\-$describe"]
140 Msg Info "Creating $dst_dir..."
141 file mkdir $dst_dir/reports
145 set confDict [dict create]
146 set allow_fail_on_conf 0
147 set allow_fail_on_list 0
148 set allow_fail_on_git 0
150 if {[
file exists "$tcl_path/../../Top/$group/$proj_name/hog.conf"]} {
151 set confDict [
ReadConf "$tcl_path/../../Top/$group/$proj_name/hog.conf"]
152 set allow_fail_on_check [
DictGet [
DictGet $confDict "hog"] "ALLOW_FAIL_ON_CHECK" 0]
153 set allow_fail_on_git [
DictGet [
DictGet $confDict "hog"] "ALLOW_FAIL_ON_GIT" 0]
154 set full_diff_log [
DictGet [
DictGet $confDict "hog"] "FULL_DIFF_LOG" 0]
162 if {![
string equal ext_path ""]} {
163 set argv [list "-ext_path" "$ext_path" "-project" "$group/$proj_name" "-outDir" "$dst_dir" "-log" "[
expr {!$allow_fail_on_check}]"]
165 set argv [list "-project" "$group/$proj_name" "-outDir" "$dst_dir" "-log" "[
expr {!$allow_fail_on_check}]"]
167 source $tcl_path/utils/check_list_files.tcl
168 if {[
file exists "$dst_dir/diff_list_and_conf.txt"]} {
169 Msg CriticalWarning "Project list or hog.conf mismatch, will use current SHA ($this_commit) and version will be set to 0."
180 Msg Info "Evaluating non committed changes..."
181 set found_uncommitted 0
183 set diff_stat [
Git "diff --stat"]
185 set found_uncommitted 1
186 Msg Warning "Found non committed changes:..."
187 if {$full_diff_log} {
190 Msg Status "$diff_stat"
192 set fp [open "$dst_dir/diff_presynthesis.txt" w+]
195 Msg CriticalWarning "Repository is not clean, will use current SHA ($this_commit) and create a dirty bitfile..."
198 lassign [
GetHogFiles -ext_path "$ext_path" "$tcl_path/../../Top/$group/$proj_name/list/" "$tcl_path/../../"] listLibraries listProperties
200 if {!$allow_fail_on_git} {
201 foreach library [dict keys $listLibraries] {
202 set fileNames [dict get $listLibraries $library]
203 foreach fileName $fileNames {
205 set fp [open "$dst_dir/diff_presynthesis.txt" a+]
206 set found_uncommitted 1
207 puts $fp "\n[
Relative $tcl_path/../../ $fileName] is not in the git repository"
208 Msg CriticalWarning "[
Relative $tcl_path/../../ $fileName] is not in the git repository. Will use current SHA ($this_commit) and version will be set to 0."
214 if {$found_uncommitted == 0} {
215 Msg Info "No uncommitted changes found."
223 lassign [
GitRet "tag -l v0.0.1"] status result
225 Msg CriticalWarning "Repository does not have an initial v0.0.1 tag yet. Please create it with \"git tag v0.0.1\" "
229 Msg Info "Git describe for $commit is: $describe"
232 set commit $this_commit
234 Msg Info "Found last SHA for $proj_name: $commit"
235 if {$commit != $this_commit} {
236 set count [
Git "rev-list --count $commit..$this_commit"]
237 Msg Info "The commit in which project $proj_name was last modified is $commit, that is $count commits older than current commit $this_commit."
241 if {$xml_hash != ""} {
242 set xml_dst [
file normalize $old_path/../xml]
243 Msg Info "Creating XML directory $xml_dst..."
245 Msg Info "Copying xml files to $xml_dst and replacing placeholders with xml version $xml_ver..."
253 set maxThreads [
GetMaxThreads [
file normalize ./Top/$group/$proj_name/]]
254 if {$maxThreads != 1} {
255 Msg CriticalWarning "Multithreading enabled. Bitfile will not be deterministic. Number of threads: $maxThreads"
257 Msg Info "Disabling multithreading to assure deterministic bitfile"
262 set_param general.maxThreads $maxThreads
265 if { [
catch {
package require ::quartus::project} ERROR] } {
266 Msg Error "$ERROR\n Can not find package ::quartus::project"
272 project_open $proj_name -current_revision
274 set_global_assignment -name NUM_PARALLEL_PROCESSORS $maxThreads
277 set_option -max_parallel_jobs $maxThreads
280 puts "Hog:DEBUG MaxThread is set to: $maxThreads"
283 set clock_seconds [
clock seconds]
284 set tt [
clock format $clock_seconds -format {%d/%m/%Y at %H:%M:%S}]
287 set date [
Git "log -1 --format=%cd --date=format:%d%m%Y $commit"]
288 set timee [
Git "log -1 --format=%cd --date=format:00%H%M%S $commit"]
290 Msg Warning "Found Git version older than 2.9.3. Using current date and time instead of commit time."
291 set date [
clock format $clock_seconds -format {%d%m%Y}]
292 set timee [
clock format $clock_seconds -format {00%H%M%S}]
298 set proj_path "$group/$proj_name"
300 WriteGenerics "synth" $proj_path $date $timee $commit $version $top_hash $top_ver $hog_hash $hog_ver $cons_ver $cons_hash $libs $vers $hashes $ext_names $ext_hashes $user_ip_repos $user_ip_vers $user_ip_hashes $flavour $xml_ver $xml_hash
301 set status_file [
file normalize "$old_path/../versions.txt"]
305 if { [
catch {
package require ::quartus::project} ERROR] } {
306 Msg Error "$ERROR\n Can not find package ::quartus::project"
312 project_open $proj_name -current_revision
315 set zero_ttb 00000000
317 binary scan [
binary format H* [
string map {{'} {}} $date]] B32 bits
318 set_parameter -name GLOBAL_DATE $bits
319 binary scan [
binary format H* [
string map {{'} {}} $timee]] B32 bits
320 set_parameter -name GLOBAL_TIME $bits
321 binary scan [
binary format H* [
string map {{'} {}} $version]] B32 bits
322 set_parameter -name GLOBAL_VER $bits
323 binary scan [
binary format H* [
string map {{'} {}} $commit]] B32 bits
324 set_parameter -name GLOBAL_SHA $bits
325 binary scan [
binary format H* [
string map {{'} {}} $top_hash]] B32 bits
326 set_parameter -name TOP_SHA $bits
327 binary scan [
binary format H* [
string map {{'} {}} $top_ver]] B32 bits
328 set_parameter -name TOP_VER $bits
329 binary scan [
binary format H* [
string map {{'} {}} $hog_hash]] B32 bits
330 set_parameter -name HOG_SHA $bits
331 binary scan [
binary format H* [
string map {{'} {}} $hog_ver]] B32 bits
332 set_parameter -name HOG_VER $bits
333 binary scan [
binary format H* [
string map {{'} {}} $cons_ver]] B32 bits
334 set_parameter -name CON_VER $bits
335 binary scan [
binary format H* [
string map {{'} {}} $cons_hash]] B32 bits
336 set_parameter -name CON_SHA $bits
338 if {$use_ipbus == 1} {
339 binary scan [
binary format H* [
string map {{'} {}} $xml_ver]] B32 bits
340 set_parameter -name XML_VER $bits
341 binary scan [
binary format H* [
string map {{'} {}} $xml_hash]] B32 bits
342 set_parameter -name XML_SHA $bits
346 foreach l $libs v $vers h $hashes {
347 binary scan [
binary format H* [
string map {{'} {}} $v]] B32 bits
348 set_parameter -name "[
string toupper $l]_VER" $bits
349 binary scan [
binary format H* [
string map {{'} {}} $h]] B32 bits
350 set_parameter -name "[
string toupper $l]_SHA" $bits
353 foreach e $ext_names h $ext_hashes {
354 binary scan [
binary format H* [
string map {{'} {}} $h]] B32 bits
355 set_parameter -name "[
string toupper $e]_SHA" $bits
358 if {$flavour != -1} {
359 set_parameter -name FLAVOUR $flavour
362 if {![
file exists "$old_path/output_files"]} {
363 file mkdir "$old_path/output_files"
366 set status_file "$old_path/output_files/versions.txt"
371 puts "Hog:DEBUG GLOBAL_DATE=$date GLOBAL_TIME=$timee"
372 puts "Hog:DEBUG GLOBAL_SHA=$commit TOP_SHA=$top_hash"
373 puts "Hog:DEBUG CON_VER=$cons_ver CON_SHA=$cons_hash"
374 puts "Hog:DEBUG XML_SHA=$xml_hash GLOBAL_VER=$version TOP_VER=$top_ver"
375 puts "Hog:DEBUG XML_VER=$xml_ver HOG_SHA=$hog_hash HOG_VER=$hog_ver"
376 puts "Hog:DEBUG LIBS: $libs $vers $hashes"
377 puts "Hog:DEBUG EXT: $ext_names $ext_hashes"
378 puts "Hog:DEBUG FLAVOUR: $flavour"
379 set status_file "$old_path/versions.txt"
382 Msg Info "Opening version file $status_file..."
383 set status_file [open $status_file "w+"]
385 Msg Status " ------------------------- PRE SYNTHESIS -------------------------"
387 Msg Status " Firmware date and time: $date, $timee"
388 if {$flavour != -1} {
389 Msg Status " Project flavour: $flavour"
394 puts $status_file "## $group/$proj_name Version Table\n"
396 puts $status_file "## $proj_name Version Table\n"
402 m add row "| \"**File set**\" | \"**Commit SHA**\" | **Version** |"
403 m add row "| --- | --- | --- |"
404 Msg Status " Global SHA: $commit, VER: $version"
405 m add row "| Global | $commit | $version |"
408 Msg Status " Constraints SHA: $cons_hash, VER: $cons_ver"
409 m add row "| Constraints | $cons_hash | $cons_ver |"
411 if {$use_ipbus == 1} {
413 Msg Status " IPbus XML SHA: $xml_hash, VER: $xml_ver"
414 m add row "| \"IPbus XML\" | $xml_hash | $xml_ver |"
417 Msg Status " Top SHA: $top_hash, VER: $top_ver"
418 m add row "| \"Top Directory\" | $top_hash | $top_ver |"
421 Msg Status " Hog SHA: $hog_hash, VER: $hog_ver"
422 m add row "| Hog | $hog_hash | $hog_ver |"
424 Msg Status " --- Libraries ---"
425 foreach l $libs v $vers h $hashes {
427 Msg Status " $l SHA: $h, VER: $v"
428 m add row "| \"**Lib:** $l\" | $h | $v |"
431 if {[
llength $user_ip_repos] > 0} {
433 Msg Status " --- User IP Repositories ---"
434 foreach r $user_ip_repos v $user_ip_vers h $user_ip_hashes {
436 set repo_name [
file tail $r]
437 Msg Status " $repo_name SHA: $h, VER: $v"
438 m add row "| \"**Repo:** $repo_name\" | $h | $v |"
442 if {[
llength $ext_names] > 0} {
443 Msg Status " --- External Libraries ---"
444 foreach e $ext_names eh $ext_hashes {
445 Msg Status " $e SHA: $eh"
446 m add row "| \"**Ext:** $e\" | $eh | \" \" |"
450 Msg Status " -----------------------------------------------------------------"
452 puts $status_file [m format 2string]
453 puts $status_file "\n\n"
460 set user_pre_synthesis_file "./Top/$group/$proj_name/pre-synthesis.tcl"
461 if {[
file exists $user_pre_synthesis_file]} {
462 Msg Info "Sourcing user pre-synthesis file $user_pre_synthesis_file"
463 source $user_pre_synthesis_file