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."
36 if {[
catch {
package require struct::matrix} ERROR]} {
37 puts "$ERROR\n If you are running this script on tclsh, you can fix this by installing 'tcllib'"
45 set project [
file tail $project_name]
46 set old_path [
file normalize "../../Projects/${project_name}/$project.runs/synth_1"]
52 if {[
info exists env(HOG_EXTERNAL_PATH)]} {
53 set ext_path $env(HOG_EXTERNAL_PATH)
54 Msg Info "Found environment variable HOG_EXTERNAL_PATH, setting path for external files to $ext_path..."
62 set proj_file "[get_property DIRECTORY [current_project]]/$project.prr"
64 set proj_file [get_property parent.project_path [current_project]]
66 set proj_dir [
file normalize [
file dirname $proj_file]]
67 set proj_name [
file rootname [
file tail $proj_file]]
70 set proj_name [
lindex $quartus(args) 1]
73 set proj_file [
file normalize "$proj_dir/$proj_name.qpf"]
75 set hogQsysFileName [
file normalize "$proj_dir/.hog/.hogQsys.md5"]
76 if { [
file exists $hogQsysFileName] != 0} {
77 set hogQsysFile [open $hogQsysFileName r]
78 set hogQsysFileLines [
split [read $hogQsysFile] "\n"]
79 foreach line $hogQsysFileLines {
80 set fileEntry [
split $line "\t"]
81 set fileEntryName [
lindex $fileEntry 0]
82 if {$fileEntryName != ""} {
83 if {[
file exists $fileEntryName]} {
84 set newMd5Sum [
Md5Sum $fileEntryName]
85 set oldMd5Sum [
lindex $fileEntry 1]
86 if { $newMd5Sum != $oldMd5Sum } {
87 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!"
90 Msg Warning "File $fileEntryName not found... Will not check Md5Sum!"
97 set proj_dir [
file normalize [
file dirname "[project_data -dir]/../.."]]
98 set proj_name [
file tail $proj_dir]
99 set project $proj_name
101 set proj_dir [
file normalize "[
pwd]/.."]
102 set proj_name [
file tail $proj_dir]
103 set project $proj_name
106 set proj_file $old_path/[
file tail $old_path].xpr
107 set proj_dir [
file normalize [
file dirname $proj_file]]
108 set proj_name [
file rootname [
file tail $proj_file]]
109 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/"
113 set repo_path [
file normalize "$tcl_path/../.."]
119 set flavour [
string map {. ""} [
file extension $proj_name]]
120 if {$flavour != ""} {
121 if {[
string is integer $flavour]} {
122 Msg Info "Project $proj_name has flavour = $flavour, the generic variable FLAVOUR will be set to $flavour"
124 Msg Warning "Project name has a unexpected non numeric extension, flavour will be set to -1"
136 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
140 set dst_dir [
file normalize "bin/$group/$proj_name\-$describe"]
141 Msg Info "Creating $dst_dir..."
142 file mkdir $dst_dir/reports
146 set confDict [dict create]
147 set allow_fail_on_conf 0
148 set allow_fail_on_list 0
149 set allow_fail_on_git 0
151 if {[
file exists "$tcl_path/../../Top/$group/$proj_name/hog.conf"]} {
152 set confDict [
ReadConf "$tcl_path/../../Top/$group/$proj_name/hog.conf"]
153 set allow_fail_on_check [
DictGet [
DictGet $confDict "hog"] "ALLOW_FAIL_ON_CHECK" 0]
154 set allow_fail_on_git [
DictGet [
DictGet $confDict "hog"] "ALLOW_FAIL_ON_GIT" 0]
155 set full_diff_log [
DictGet [
DictGet $confDict "hog"] "FULL_DIFF_LOG" 0]
162 Msg Info "Running list file checker..."
164 if {![
string equal ext_path ""]} {
165 set argv [list "-ext_path" "$ext_path" "-project" "$group/$proj_name" "-outDir" "$dst_dir" "-log" "[
expr {!$allow_fail_on_check}]"]
167 set argv [list "-project" "$group/$proj_name" "-outDir" "$dst_dir" "-log" "[
expr {!$allow_fail_on_check}]"]
169 source $tcl_path/utils/check_list_files.tcl
170 if {[
file exists "$dst_dir/diff_list_and_conf.txt"]} {
171 Msg CriticalWarning "Project list or hog.conf mismatch, will use current SHA ($this_commit) and version will be set to 0."
182 Msg Info "Evaluating non committed changes..."
183 set found_uncommitted 0
185 set diff_stat [
Git "diff --stat"]
187 set found_uncommitted 1
188 Msg Warning "Found non committed changes:..."
189 if {$full_diff_log} {
192 Msg Status "$diff_stat"
194 set fp [open "$dst_dir/diff_presynthesis.txt" w+]
197 Msg CriticalWarning "Repository is not clean, will use current SHA ($this_commit) and create a dirty bitfile..."
200 lassign [
GetHogFiles -ext_path "$ext_path" "$tcl_path/../../Top/$group/$proj_name/list/" "$tcl_path/../../"] listLibraries listProperties
202 if {!$allow_fail_on_git} {
203 foreach library [dict keys $listLibraries] {
204 set fileNames [dict get $listLibraries $library]
205 foreach fileName $fileNames {
207 set fp [open "$dst_dir/diff_presynthesis.txt" a+]
208 set found_uncommitted 1
209 puts $fp "\n[
Relative $tcl_path/../../ $fileName] is not in the git repository"
210 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."
216 if {$found_uncommitted == 0} {
217 Msg Info "No uncommitted changes found."
225 lassign [
GitRet "tag -l v0.0.1"] status result
227 Msg CriticalWarning "Repository does not have an initial v0.0.1 tag yet. Please create it with \"git tag v0.0.1\" "
231 Msg Info "Git describe for $commit is: $describe"
234 set commit $this_commit
236 Msg Info "Found last SHA for $proj_name: $commit"
237 if {$commit != $this_commit} {
238 set count [
Git "rev-list --count $commit..$this_commit"]
239 Msg Info "The commit in which project $proj_name was last modified is $commit, that is $count commits older than current commit $this_commit."
243 if {$xml_hash != ""} {
244 set xml_dst [
file normalize $old_path/../xml]
245 Msg Info "Creating XML directory $xml_dst..."
247 Msg Info "Copying xml files to $xml_dst and replacing placeholders with xml version $xml_ver..."
256 set maxThreads [
GetMaxThreads [
file normalize ./Top/$group/$proj_name/]]
258 if {$maxThreads != 1} {
259 Msg CriticalWarning "Multithreading enabled. Bitfile will not be deterministic. Number of threads: $maxThreads"
261 Msg Info "Disabling multithreading to assure deterministic bitfile"
266 set_param general.maxThreads $maxThreads
269 if { [
catch {
package require ::quartus::project} ERROR] } {
270 Msg Error "$ERROR\n Can not find package ::quartus::project"
276 project_open $proj_name -current_revision
278 set_global_assignment -name NUM_PARALLEL_PROCESSORS $maxThreads
281 set_option -max_parallel_jobs $maxThreads
284 set clock_seconds [
clock seconds]
285 set tt [
clock format $clock_seconds -format {%d/%m/%Y at %H:%M:%S}]
288 set date [
Git "log -1 --format=%cd --date=format:%d%m%Y $commit"]
289 set timee [
Git "log -1 --format=%cd --date=format:00%H%M%S $commit"]
291 Msg Warning "Found Git version older than 2.9.3. Using current date and time instead of commit time."
292 set date [
clock format $clock_seconds -format {%d%m%Y}]
293 set timee [
clock format $clock_seconds -format {00%H%M%S}]
299 set proj_group_and_name "$group/$proj_name"
302 prj_project open $proj_dir/$proj_name.ldf
304 WriteGenerics "synth" $repo_path $proj_group_and_name $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
309 set status_file [
file normalize "$old_path/../versions.txt"]
313 if { [
catch {
package require ::quartus::project} ERROR] } {
314 Msg Error "$ERROR\n Can not find package ::quartus::project"
320 project_open $proj_name -current_revision
323 set zero_ttb 00000000
325 binary scan [
binary format H* [
string map {{'} {}} $date]] B32 bits
326 set_parameter -name GLOBAL_DATE $bits
327 binary scan [
binary format H* [
string map {{'} {}} $timee]] B32 bits
328 set_parameter -name GLOBAL_TIME $bits
329 binary scan [
binary format H* [
string map {{'} {}} $version]] B32 bits
330 set_parameter -name GLOBAL_VER $bits
331 binary scan [
binary format H* [
string map {{'} {}} $commit]] B32 bits
332 set_parameter -name GLOBAL_SHA $bits
333 binary scan [
binary format H* [
string map {{'} {}} $top_hash]] B32 bits
334 set_parameter -name TOP_SHA $bits
335 binary scan [
binary format H* [
string map {{'} {}} $top_ver]] B32 bits
336 set_parameter -name TOP_VER $bits
337 binary scan [
binary format H* [
string map {{'} {}} $hog_hash]] B32 bits
338 set_parameter -name HOG_SHA $bits
339 binary scan [
binary format H* [
string map {{'} {}} $hog_ver]] B32 bits
340 set_parameter -name HOG_VER $bits
341 binary scan [
binary format H* [
string map {{'} {}} $cons_ver]] B32 bits
342 set_parameter -name CON_VER $bits
343 binary scan [
binary format H* [
string map {{'} {}} $cons_hash]] B32 bits
344 set_parameter -name CON_SHA $bits
346 if {$use_ipbus == 1} {
347 binary scan [
binary format H* [
string map {{'} {}} $xml_ver]] B32 bits
348 set_parameter -name XML_VER $bits
349 binary scan [
binary format H* [
string map {{'} {}} $xml_hash]] B32 bits
350 set_parameter -name XML_SHA $bits
354 foreach l $libs v $vers h $hashes {
355 binary scan [
binary format H* [
string map {{'} {}} $v]] B32 bits
356 set_parameter -name "[
string toupper $l]_VER" $bits
357 binary scan [
binary format H* [
string map {{'} {}} $h]] B32 bits
358 set_parameter -name "[
string toupper $l]_SHA" $bits
361 foreach e $ext_names h $ext_hashes {
362 binary scan [
binary format H* [
string map {{'} {}} $h]] B32 bits
363 set_parameter -name "[
string toupper $e]_SHA" $bits
366 if {$flavour != -1} {
367 set_parameter -name FLAVOUR $flavour
370 if {![
file exists "$old_path/output_files"]} {
371 file mkdir "$old_path/output_files"
374 set status_file "$old_path/output_files/versions.txt"
379 puts "Hog:DEBUG GLOBAL_DATE=$date GLOBAL_TIME=$timee"
380 puts "Hog:DEBUG GLOBAL_SHA=$commit TOP_SHA=$top_hash"
381 puts "Hog:DEBUG CON_VER=$cons_ver CON_SHA=$cons_hash"
382 puts "Hog:DEBUG XML_SHA=$xml_hash GLOBAL_VER=$version TOP_VER=$top_ver"
383 puts "Hog:DEBUG XML_VER=$xml_ver HOG_SHA=$hog_hash HOG_VER=$hog_ver"
384 puts "Hog:DEBUG LIBS: $libs $vers $hashes"
385 puts "Hog:DEBUG EXT: $ext_names $ext_hashes"
386 puts "Hog:DEBUG FLAVOUR: $flavour"
387 set status_file "$old_path/versions.txt"
390 Msg Info "Opening version file $status_file..."
391 set status_file [open $status_file "w+"]
393 Msg Status " ------------------------- PRE SYNTHESIS -------------------------"
395 Msg Status " Firmware date and time: $date, $timee"
396 if {$flavour != -1} {
397 Msg Status " Project flavour: $flavour"
402 puts $status_file "## $group/$proj_name Version Table\n"
404 puts $status_file "## $proj_name Version Table\n"
410 m add row "| \"**File set**\" | \"**Commit SHA**\" | **Version** |"
411 m add row "| --- | --- | --- |"
412 Msg Status " Global SHA: $commit, VER: $version"
413 m add row "| Global | $commit | $version |"
416 Msg Status " Constraints SHA: $cons_hash, VER: $cons_ver"
417 m add row "| Constraints | $cons_hash | $cons_ver |"
419 if {$use_ipbus == 1} {
421 Msg Status " IPbus XML SHA: $xml_hash, VER: $xml_ver"
422 m add row "| \"IPbus XML\" | $xml_hash | $xml_ver |"
425 Msg Status " Top SHA: $top_hash, VER: $top_ver"
426 m add row "| \"Top Directory\" | $top_hash | $top_ver |"
429 Msg Status " Hog SHA: $hog_hash, VER: $hog_ver"
430 m add row "| Hog | $hog_hash | $hog_ver |"
432 Msg Status " --- Libraries ---"
433 foreach l $libs v $vers h $hashes {
435 Msg Status " $l SHA: $h, VER: $v"
436 m add row "| \"**Lib:** $l\" | $h | $v |"
439 if {[
llength $user_ip_repos] > 0} {
441 Msg Status " --- User IP Repositories ---"
442 foreach r $user_ip_repos v $user_ip_vers h $user_ip_hashes {
444 set repo_name [
file tail $r]
445 Msg Status " $repo_name SHA: $h, VER: $v"
446 m add row "| \"**Repo:** $repo_name\" | $h | $v |"
450 if {[
llength $ext_names] > 0} {
451 Msg Status " --- External Libraries ---"
452 foreach e $ext_names eh $ext_hashes {
453 Msg Status " $e SHA: $eh"
454 m add row "| \"**Ext:** $e\" | $eh | \" \" |"
458 Msg Status " -----------------------------------------------------------------"
460 puts $status_file [m format 2string]
461 puts $status_file "\n\n"
468 set user_pre_synthesis_file "./Top/$group/$proj_name/pre-synthesis.tcl"
469 if {[
file exists $user_pre_synthesis_file]} {
470 Msg Info "Sourcing user pre-synthesis file $user_pre_synthesis_file"
471 source $user_pre_synthesis_file