24 set tcl_path [
file normalize "[
file dirname [
info script]]/.."]
25 source $tcl_path/hog.tcl
29 if {[
info exists env(HOG_TCLLIB_PATH)]} {
30 lappend auto_path $env(HOG_TCLLIB_PATH)
32 puts "ERROR: To run Hog with Microsemi Libero SoC, you need to define the HOG_TCLLIB_PATH variable."
37 if {[
catch {
package require struct::matrix} ERROR]} {
38 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 is not equal to the one saved in $hogQsysFileName.\n\
88 New checksum $newMd5Sum, old checksum $oldMd5Sum. \
89 Please check the any changes in the file are correctly propagated to git!"
92 Msg Warning "File $fileEntryName not found... Will not check Md5Sum!"
98 set proj_dir [
file normalize [
file dirname "[project_data -dir]/../.."]]
99 set proj_name [
file tail $proj_dir]
100 set project $proj_name
102 set proj_dir [
file normalize "[
pwd]/.."]
103 set proj_name [
file tail $proj_dir]
104 set project $proj_name
107 set proj_file $old_path/[
file tail $old_path].xpr
108 set proj_dir [
file normalize [
file dirname $proj_file]]
109 set proj_name [
file rootname [
file tail $proj_file]]
110 Msg CriticalWarning "You seem to be running locally on tclsh, so this is a debug message. \
111 The project file will be set to $proj_file and was derived from the path you launched this script from: $old_path. \
112 If you want this script to work properly in debug mode, please launch it from the top folder of one project, \
113 for example Repo/Projects/fpga1/ or Repo/Top/fpga1/"
116 Notify Info "Starting synthesis of $proj_name."
119 set repo_path [
file normalize "$tcl_path/../.."]
125 set flavour [
string map {. ""} [
file extension $proj_name]]
126 if {$flavour != ""} {
127 if {[
string is integer $flavour]} {
128 Msg Info "Project $proj_name has flavour = $flavour, the generic variable FLAVOUR will be set to $flavour"
130 Msg Warning "Project name has a unexpected non numeric extension, flavour will be set to -1"
141 set top_dir [
file normalize $repo_path/Top/$group/$proj_name]
143 commit version hog_hash hog_ver \
146 cons_ver cons_hash ext_names ext_hashes \
147 xml_hash xml_ver user_ip_repos user_ip_hashes user_ip_vers \
152 set dst_dir [
file normalize "bin/$group/$proj_name\-$describe"]
153 Msg Info "Creating $dst_dir..."
154 file mkdir $dst_dir/reports
158 set confDict [dict create]
159 set allow_fail_on_conf 0
160 set allow_fail_on_list 0
161 set allow_fail_on_git 0
163 if {[
file exists "$tcl_path/../../Top/$group/$proj_name/hog.conf"]} {
164 set confDict [
ReadConf "$tcl_path/../../Top/$group/$proj_name/hog.conf"]
165 set allow_fail_on_check [
DictGet [
DictGet $confDict "hog"] "ALLOW_FAIL_ON_CHECK" 0]
166 set allow_fail_on_git [
DictGet [
DictGet $confDict "hog"] "ALLOW_FAIL_ON_GIT" 0]
167 set full_diff_log [
DictGet [
DictGet $confDict "hog"] "FULL_DIFF_LOG" 0]
174 Msg Info "Running list file checker..."
176 if {![
string equal ext_path ""]} {
177 set argv [list "-ext_path" "$ext_path" "-project" "$group/$proj_name" "-outDir" "$dst_dir" "-log" "[
expr {!$allow_fail_on_check}]"]
179 set argv [list "-project" "$group/$proj_name" "-outDir" "$dst_dir" "-log" "[
expr {!$allow_fail_on_check}]"]
181 source $tcl_path/utils/check_list_files.tcl
182 if {[
file exists "$dst_dir/diff_list_and_conf.txt"]} {
183 Msg CriticalWarning "Project list or hog.conf mismatch, will use current SHA ($this_commit) and version will be set to 0."
194 Msg Info "Evaluating non committed changes..."
195 set found_uncommitted 0
197 set diff_stat [
Git "diff --stat"]
199 set found_uncommitted 1
200 Msg Warning "Found non committed changes:..."
201 if {$full_diff_log} {
204 Msg Status "$diff_stat"
206 set fp [open "$dst_dir/diff_presynthesis.txt" w+]
209 Msg CriticalWarning "Repository is not clean, will use current SHA ($this_commit) and create a dirty bitfile..."
212 lassign [
GetHogFiles -ext_path "$ext_path" "$tcl_path/../../Top/$group/$proj_name/list/" "$tcl_path/../../"] listLibraries listProperties
214 if {!$allow_fail_on_git} {
215 foreach library [dict keys $listLibraries] {
216 set fileNames [dict get $listLibraries $library]
217 foreach fileName $fileNames {
219 set fp [open "$dst_dir/diff_presynthesis.txt" a+]
220 set found_uncommitted 1
221 puts $fp "\n[
Relative $tcl_path/../../ $fileName] is not in the git repository"
222 Msg CriticalWarning "[
Relative $tcl_path/../../ $fileName] is not in the git repository. \
223 Will use current SHA ($this_commit) and version will be set to 0."
229 if {$found_uncommitted == 0} {
230 Msg Info "No uncommitted changes found."
238 lassign [
GitRet "tag -l v0.0.1"] status result
240 Msg CriticalWarning "Repository does not have an initial v0.0.1 tag yet. Please create it with \"git tag v0.0.1\" "
244 Msg Info "Git describe for $commit is: $describe"
247 set commit $this_commit
249 Msg Info "Found last SHA for $proj_name: $commit"
250 if {$commit != $this_commit} {
251 set count [
Git "rev-list --count $commit..$this_commit"]
252 Msg Info "The commit in which project $proj_name was last modified is $commit, that is $count commits older than current commit $this_commit."
256 if {$xml_hash != ""} {
257 set xml_dst [
file normalize $old_path/../xml]
258 Msg Info "Creating XML directory $xml_dst..."
260 Msg Info "Copying xml files to $xml_dst and replacing placeholders with xml version $xml_ver..."
267 if {$cheby_hash != ""} {
268 set cheby_dst [
file normalize $old_path/../cheby]
269 Msg Info "Creating Cheby directory $cheby_dst..."
270 file mkdir $cheby_dst
271 Msg Info "Verifying Cheby outputs against the .chb list files..."
272 set cheby_tool "cheby"
273 if {[
info exists env(HOG_CHEBY_TOOL)]} {
274 set cheby_tool $env(HOG_CHEBY_TOOL)
285 set maxThreads [
GetMaxThreads [
file normalize ./Top/$group/$proj_name/]]
287 if {$maxThreads != 1} {
288 Msg Warning "Multithreading enabled. Bitfile will not be deterministic. Number of threads: $maxThreads"
290 Msg Info "Disabling multithreading to assure deterministic bitfile"
295 set_param general.maxThreads $maxThreads
298 if {[
catch {
package require ::quartus::project} ERROR]} {
299 Msg Error "$ERROR\n Can not find package ::quartus::project"
305 project_open $proj_name -current_revision
307 set_global_assignment -name NUM_PARALLEL_PROCESSORS $maxThreads
310 set_option -max_parallel_jobs $maxThreads
313 set clock_seconds [
clock seconds]
314 set tt [
clock format $clock_seconds -format {%d/%m/%Y at %H:%M:%S}]
317 set date [
Git "log -1 --format=%cd --date=format:%d%m%Y $commit"]
318 set timee [
Git "log -1 --format=%cd --date=format:00%H%M%S $commit"]
320 Msg Warning "Found Git version older than 2.9.3. Using current date and time instead of commit time."
321 set date [
clock format $clock_seconds -format {%d%m%Y}]
322 set timee [
clock format $clock_seconds -format {00%H%M%S}]
328 set proj_group_and_name "$group/$proj_name"
331 prj_project open $proj_dir/$proj_name.ldf
333 WriteGenerics "synth" $repo_path $proj_group_and_name $date $timee $commit $version \
334 $top_hash $top_ver $hog_hash $hog_ver \
335 $cons_ver $cons_hash $libs $vers \
336 $hashes $ext_names $ext_hashes \
337 $user_ip_repos $user_ip_vers $user_ip_hashes \
338 $flavour $xml_ver $xml_hash $cheby_ver $cheby_hash
344 set status_file [
file normalize "$old_path/../versions.txt"]
347 if {[
catch {
package require ::quartus::project} ERROR]} {
348 Msg Error "$ERROR\n Can not find package ::quartus::project"
354 project_open $proj_name -current_revision
357 set zero_ttb 00000000
359 binary scan [
binary format H* [
string map {{'} {}} $date]] B32 bits
360 set_parameter -name GLOBAL_DATE $bits
361 binary scan [
binary format H* [
string map {{'} {}} $timee]] B32 bits
362 set_parameter -name GLOBAL_TIME $bits
363 binary scan [
binary format H* [
string map {{'} {}} $version]] B32 bits
364 set_parameter -name GLOBAL_VER $bits
365 binary scan [
binary format H* [
string map {{'} {}} $commit]] B32 bits
366 set_parameter -name GLOBAL_SHA $bits
367 binary scan [
binary format H* [
string map {{'} {}} $top_hash]] B32 bits
368 set_parameter -name TOP_SHA $bits
369 binary scan [
binary format H* [
string map {{'} {}} $top_ver]] B32 bits
370 set_parameter -name TOP_VER $bits
371 binary scan [
binary format H* [
string map {{'} {}} $hog_hash]] B32 bits
372 set_parameter -name HOG_SHA $bits
373 binary scan [
binary format H* [
string map {{'} {}} $hog_ver]] B32 bits
374 set_parameter -name HOG_VER $bits
375 binary scan [
binary format H* [
string map {{'} {}} $cons_ver]] B32 bits
376 set_parameter -name CON_VER $bits
377 binary scan [
binary format H* [
string map {{'} {}} $cons_hash]] B32 bits
378 set_parameter -name CON_SHA $bits
380 if {$use_ipbus == 1} {
381 binary scan [
binary format H* [
string map {{'} {}} $xml_ver]] B32 bits
382 set_parameter -name XML_VER $bits
383 binary scan [
binary format H* [
string map {{'} {}} $xml_hash]] B32 bits
384 set_parameter -name XML_SHA $bits
387 if {$use_cheby == 1} {
388 binary scan [
binary format H* [
string map {{'} {}} $cheby_ver]] B32 bits
389 set_parameter -name CHEBY_VER $bits
390 binary scan [
binary format H* [
string map {{'} {}} $cheby_hash]] B32 bits
391 set_parameter -name CHEBY_SHA $bits
395 foreach l $libs v $vers h $hashes {
396 binary scan [
binary format H* [
string map {{'} {}} $v]] B32 bits
397 set_parameter -name "[
string toupper $l]_VER" $bits
398 binary scan [
binary format H* [
string map {{'} {}} $h]] B32 bits
399 set_parameter -name "[
string toupper $l]_SHA" $bits
402 foreach e $ext_names h $ext_hashes {
403 binary scan [
binary format H* [
string map {{'} {}} $h]] B32 bits
404 set_parameter -name "[
string toupper $e]_SHA" $bits
407 if {$flavour != -1} {
408 set_parameter -name FLAVOUR $flavour
411 if {![
file exists "$old_path/output_files"]} {
412 file mkdir "$old_path/output_files"
415 set status_file "$old_path/output_files/versions.txt"
419 puts "Hog:DEBUG GLOBAL_DATE=$date GLOBAL_TIME=$timee"
420 puts "Hog:DEBUG GLOBAL_SHA=$commit TOP_SHA=$top_hash"
421 puts "Hog:DEBUG CON_VER=$cons_ver CON_SHA=$cons_hash"
422 puts "Hog:DEBUG XML_SHA=$xml_hash GLOBAL_VER=$version TOP_VER=$top_ver"
423 puts "Hog:DEBUG XML_VER=$xml_ver HOG_SHA=$hog_hash HOG_VER=$hog_ver"
424 puts "Hog:DEBUG CHEBY_SHA=$cheby_hash CHEBY_VER=$cheby_ver"
425 puts "Hog:DEBUG LIBS: $libs $vers $hashes"
426 puts "Hog:DEBUG EXT: $ext_names $ext_hashes"
427 puts "Hog:DEBUG FLAVOUR: $flavour"
428 set status_file "$old_path/versions.txt"
430 Msg Info "Opening version file $status_file..."
431 set status_file [open $status_file "w+"]
433 Msg Status " ------------------------- PRE SYNTHESIS -------------------------"
435 Msg Status " Firmware date and time: $date, $timee"
436 if {$flavour != -1} {
437 Msg Status " Project flavour: $flavour"
442 puts $status_file "## $group/$proj_name Version Table\n"
444 puts $status_file "## $proj_name Version Table\n"
450 m add row "| \"**File set**\" | \"**Commit SHA**\" | **Version** |"
451 m add row "| --- | --- | --- |"
452 Msg Status " Global SHA: $commit, VER: $version"
453 m add row "| Global | $commit | $version |"
456 Msg Status " Constraints SHA: $cons_hash, VER: $cons_ver"
457 m add row "| Constraints | $cons_hash | $cons_ver |"
459 if {$use_ipbus == 1} {
461 Msg Status " IPbus XML SHA: $xml_hash, VER: $xml_ver"
462 m add row "| \"IPbus XML\" | $xml_hash | $xml_ver |"
464 if {$use_cheby == 1} {
466 Msg Status " Cheby SHA: $cheby_hash, VER: $cheby_ver"
467 m add row "| \"Cheby\" | $cheby_hash | $cheby_ver |"
470 Msg Status " Top SHA: $top_hash, VER: $top_ver"
471 m add row "| \"Top Directory\" | $top_hash | $top_ver |"
474 Msg Status " Hog SHA: $hog_hash, VER: $hog_ver"
475 m add row "| Hog | $hog_hash | $hog_ver |"
477 Msg Status " --- Libraries ---"
478 foreach l $libs v $vers h $hashes {
480 Msg Status " $l SHA: $h, VER: $v"
481 m add row "| \"**Lib:** $l\" | $h | $v |"
484 if {[
llength $user_ip_repos] > 0} {
485 Msg Status " --- User IP Repositories ---"
486 foreach r $user_ip_repos v $user_ip_vers h $user_ip_hashes {
488 set repo_name [
file tail $r]
489 Msg Status " $repo_name SHA: $h, VER: $v"
490 m add row "| \"**Repo:** $repo_name\" | $h | $v |"
494 if {[
llength $ext_names] > 0} {
495 Msg Status " --- External Libraries ---"
496 foreach e $ext_names eh $ext_hashes {
497 Msg Status " $e SHA: $eh"
498 m add row "| \"**Ext:** $e\" | $eh | \" \" |"
502 Msg Status " -----------------------------------------------------------------"
504 puts $status_file [m format 2string]
505 puts $status_file "\n\n"
512 set user_pre_synthesis_file "./Top/$group/$proj_name/pre-synthesis.tcl"
513 if {[
file exists $user_pre_synthesis_file]} {
514 Msg Info "Sourcing user pre-synthesis file $user_pre_synthesis_file"
515 source $user_pre_synthesis_file