22 set tcl_path [
file normalize "[
file dirname [
info script]]/.."]
23 source $tcl_path/hog.tcl
24 set repo_path [
file normalize "$tcl_path/../../"]
29 proc WriteHwPlatformWorkaround {proj_dir proj_name work_path hw_platform_args} {
30 set proj_file [
file normalize "$proj_dir/$proj_name.xpr"]
31 set impl_run [
file tail $work_path]
32 set tmp_script "$work_path/hog_write_hw_platform_tmp.tcl"
34 set fp [open $tmp_script w]
35 puts $fp "open_project {$proj_file}"
36 puts $fp "open_run $impl_run"
37 puts $fp "write_hw_platform $hw_platform_args"
38 puts $fp "close_project"
41 Msg Info "Launching another Vivado instance to run write_hw_platform for $impl_run..."
42 set ret [
catch {
exec vivado -mode batch -notrace -source $tmp_script >@ stdout 2>@ stderr} result]
45 Msg Error "write_hw_platform failed in separate Vivado instance:\n$result"
47 Msg Info "write_hw_platform completed successfully in separate Vivado instance for $impl_run."
54 if {[
info exists env(HOG_TCLLIB_PATH)]} {
55 lappend auto_path $env(HOG_TCLLIB_PATH)
57 puts "ERROR: To run Hog with Microsemi Libero SoC, you need to define the HOG_TCLLIB_PATH variable."
62 if {[
info exists env(HOG_EXTERNAL_PATH)]} {
63 set ext_path $env(HOG_EXTERNAL_PATH)
64 Msg Info "Found environment variable HOG_EXTERNAL_PATH, setting path for external files to $ext_path..."
69 set bin_dir [
file normalize "$repo_path/bin"]
78 set work_path [get_property DIRECTORY [get_runs impl_1]]
81 set work_path $old_path
82 if {[
IsVersal [get_property PART [current_design]]]} {
88 set main_files [lsort [glob -nocomplain "$work_path/*.$fw_file_ext"]]
89 if {[
llength $main_files] > 1} {
92 set main_file [
file normalize [
lindex $main_files 1]]
94 set secondary_file [
file normalize [
lindex $main_files 0]]
95 set main_file_suffix "_pld"
96 set secondary_file_suffix "_boot"
97 Msg Info "Found main and secondary binary file main: [
file tail $main_file], secondary: [
file tail $secondary_file]..."
99 set top_name [regsub $main_file_suffix\$ [
file rootname [
file tail $main_file]] ""]
100 if {[
llength $main_files] > 2} {
101 Msg Warning "Multiple (more than 2) binary files found: $main_files."
104 set main_file [
file normalize [
lindex $main_files 0]]
105 set main_file_suffix ""
106 set secondary_file ""
107 set secondary_file_suffix ""
108 set top_name [
file rootname [
file tail $main_file]]
112 set proj_name [
file tail [
file normalize $work_path/../../]]
113 set proj_dir [
file normalize "$work_path/../.."]
116 set additional_ext ".bin .ltx .bif .mmi"
118 set xml_dir [
file normalize "$work_path/../xml"]
119 set run_dir [
file normalize "$work_path/.."]
123 set proj_name [
lindex $quartus(args) 1]
125 set xml_dir [
file normalize "$repo_path/xml"]
126 set run_dir [
file normalize "$proj_dir"]
127 set name [
file rootname [
file tail [
file normalize [
pwd]]]]
129 set pof_file [
file normalize "$proj_dir/output_files/$proj_name.pof"]
131 set sof_file [
file normalize "$proj_dir/output_files/$proj_name.sof"]
133 set rbf_file [
file normalize "$proj_dir/output_files/$proj_name.rbf"]
135 set rpd_file [
file normalize "$proj_dir/output_files/$proj_name.rpd"]
137 set stp_file [
file normalize "$proj_dir/output_files/$proj_name.stp"]
139 set spf_file [
file normalize "$proj_dir/output_files/$proj_name.spf"]
143 set proj_name $project
145 set proj_dir $main_folder
146 set map_file [
file normalize [
lindex [glob -nocomplain "$proj_dir/synthesis/*.map"] 0]]
147 set sap_file [
file normalize [
lindex [glob -nocomplain "$proj_dir/synthesis/*.sap"] 0]]
148 set srd_file [
file normalize [
lindex [glob -nocomplain "$proj_dir/synthesis/*.srd"] 0]]
149 set srm_file [
file normalize [
lindex [glob -nocomplain "$proj_dir/synthesis/*.srm"] 0]]
150 set srs_file [
file normalize [
lindex [glob -nocomplain "$proj_dir/synthesis/*.srs"] 0]]
151 set srr_file [
file normalize [
lindex [glob -nocomplain "$proj_dir/synthesis/*.srr"] 0]]
152 set top_name [
file rootname [
file tail $srr_file]]
153 set stxt_files [glob -nocomplain "$proj_dir/synthesis/*.txt"]
154 set scsv_files [glob -nocomplain "$proj_dir/synthesis/*.csv"]
155 set slog_files [glob -nocomplain "$proj_dir/synthesis/*.log"]
156 set srpt_files [glob -nocomplain "$proj_dir/synthesis/*.rpt"]
157 set dtxt_files [glob -nocomplain "$proj_dir/designer/$top_name/*.txt"]
158 set dcsv_files [glob -nocomplain "$proj_dir/designer/$top_name/*.csv"]
159 set dlog_files [glob -nocomplain "$proj_dir/designer/$top_name/*.log"]
160 set drpt_files [glob -nocomplain "$proj_dir/designer/$top_name/*.rpt"]
161 set xml_dir [
file normalize "$repo_path/xml"]
163 set proj_dir [
file normalize "[
pwd]/.."]
164 set proj_name [
file tail $proj_dir]
165 set project $proj_name
166 set xml_dir [
file normalize "$repo_path/xml"]
167 set main_file [
file normalize "$proj_dir/Implementation0/${proj_name}_Implementation0"]
170 set work_path $old_path
171 set fw_file [
file normalize [
lindex [glob -nocomplain "$work_path/*.bit"] 0]]
172 set proj_name [
file tail [
file normalize $work_path/../../]]
173 set proj_dir [
file normalize "$work_path/../.."]
175 set top_name [
file rootname [
file tail $fw_file]]
177 set main_file [
file normalize "$work_path/$top_name.bit"]
178 set bin_file [
file normalize "$work_path/$top_name.bin"]
179 set ltx_file [
file normalize "$work_path/$top_name.ltx"]
181 set xml_dir [
file normalize "$work_path/../xml"]
182 set run_dir [
file normalize "$work_path/.."]
185 set group_name [
GetGroupName $proj_dir "$tcl_path/../.."]
189 Msg Info "Evaluating Hog describe for $proj_name..."
190 set describe [
GetHogDescribe [
file normalize ./Top/$group_name/$proj_name] $repo_path]
191 Msg Info "Hog describe set to: $describe"
193 set dst_dir [
file normalize "$bin_dir/$group_name/$proj_name\-$describe"]
194 set dst_xml [
file normalize "$dst_dir/xml"]
196 Msg Info "Creating $dst_dir..."
199 set ts [
clock format [
clock seconds] -format {%Y-%m-%d-%H-%M}]
203 if {[
IsXilinx] && [
file exists $main_file]} {
204 set dst_main [
file normalize "$dst_dir/$proj_name$main_file_suffix\-$describe.$fw_file_ext"]
205 Msg Info "Copying main binary file $main_file into $dst_main..."
206 file copy -force $main_file $dst_main
207 if {$secondary_file != ""} {
208 set dst_secondary [
file normalize "$dst_dir/$proj_name$secondary_file_suffix\-$describe.$fw_file_ext"]
209 Msg Info "Copying secondary binary file $secondary_file into $dst_secondary..."
210 file copy -force $secondary_file $dst_secondary
218 lappend ltx_files "$top_name.ltx"
220 if {$main_file_suffix != ""} {
221 foreach e $additional_ext {
223 lappend new_ext $main_file_suffix$e
224 lappend new_ext $secondary_file_suffix$e
225 lappend ltx_files "$top_name$main_file_suffix.ltx"
226 lappend ltx_files "$top_name$secondary_file_suffix.ltx"
228 set additional_ext $new_ext
233 foreach l $ltx_files {
234 set ltx_file "$work_path/$l"
235 Msg Info "Writing debug probes for $ltx_file..."
236 write_debug_probes -quiet $ltx_file
239 foreach e $additional_ext {
240 set orig [
file normalize "$work_path/$top_name$e"]
241 set dst [
file normalize "$dst_dir/$proj_name\-$describe$e"]
242 if {[
file exists $work_path/$top_name$e] == 1} {
243 Msg Info "Copying $orig file into $dst..."
244 file copy -force $orig $dst
246 Msg Debug "File: $orig not found."
250 set dst_pof [
file normalize "$dst_dir/$name\-$describe.pof"]
251 set dst_sof [
file normalize "$dst_dir/$name\-$describe.sof"]
252 set dst_rbf [
file normalize "$dst_dir/$name\-$describe.rbf"]
253 set dst_rpd [
file normalize "$dst_dir/$name\-$describe.rpd"]
254 set dst_stp [
file normalize "$dst_dir/$name\-$describe.stp"]
255 set dst_spf [
file normalize "$dst_dir/$name\-$describe.spf"]
256 set dst_xml [
file normalize "$dst_dir/xml"]
258 Msg Info "Evaluating differences with last commit..."
259 set found_uncommitted 0
262 set found_uncommitted 1
263 Msg Warning "Found non committed changes:"
265 set fp [open "$dst_dir/diff_postbistream.txt" w+]
270 if {$found_uncommitted == 0} {
271 Msg Info "No uncommitted changes found."
275 if {[
file exists $pof_file]} {
276 Msg Info "Copying pof file $pof_file into $dst_pof..."
277 file copy -force $pof_file $dst_pof
279 Msg Info "No pof file found: $pof_file, that is not a problem"
283 file mkdir $dst_dir/reports
284 set reps [glob -nocomplain "$proj_dir/output_files/*.rpt"]
286 if {[
file exists [
lindex $reps 0]]} {
287 file copy -force {*}$reps $dst_dir/reports
289 Msg Warning "No reports found in $proj_dir/output_files subfolders"
293 if {[
file exists $sof_file]} {
294 Msg Info "Copying sof file $sof_file into $dst_sof..."
295 file copy -force $sof_file $dst_sof
297 Msg Info "No sof file found: $sof_file, that is not a problem"
302 if {[
file exists $rbf_file] || [
file exists $rpd_file]} {
303 if {[
file exists $rbf_file]} {
304 file copy -force $rbf_file $dst_rbf
306 if {[
file exists $rpd_file]} {
307 file copy -force $rpd_file $dst_rpd
310 Msg Info "No rbf or rpd file found: this is not a problem"
314 if {[
file exists $stp_file] || [
file exists $spf_file]} {
315 if {[
file exists $stp_file]} {
316 file copy -force $stp_file $dst_stp
318 if {[
file exists $spf_file]} {
319 file copy -force $spf_file $dst_spf
322 Msg Info "No stp or spf file found: that is not a problem"
325 set dst_map [
file normalize "$dst_dir/$project\-$describe.map"]
326 set dst_sap [
file normalize "$dst_dir/$project\-$describe.sap"]
327 set dst_srd [
file normalize "$dst_dir/$project\-$describe.srd"]
328 set dst_srm [
file normalize "$dst_dir/$project\-$describe.srm"]
329 set dst_srs [
file normalize "$dst_dir/$project\-$describe.srs"]
330 set dst_srr [
file normalize "$dst_dir/$project\-$describe.srr"]
331 set dst_rpt [
file normalize "$dst_dir/reports"]
332 set dst_xml [
file normalize "$dst_dir/xml"]
334 file mkdir $dst_dir/reports
336 if {[
file exists $map_file]} {
337 Msg Info "Copying map file $map_file into $dst_map..."
338 file copy -force $map_file $dst_map
341 if {[
file exists $sap_file]} {
342 Msg Info "Copying sap file $sap_file into $dst_sap..."
343 file copy -force $sap_file $dst_sap
346 if {[
file exists $srd_file]} {
347 Msg Info "Copying srd file $srd_file into $dst_srd..."
348 file copy -force $srd_file $dst_srd
351 if {[
file exists $srm_file]} {
352 Msg Info "Copying srm file $srm_file into $dst_srm..."
353 file copy -force $srm_file $dst_map
356 if {[
file exists $srs_file]} {
357 Msg Info "Copying srs file $srs_file into $dst_srs..."
358 file copy -force $srs_file $dst_srs
361 if {[
file exists $srr_file]} {
362 Msg Info "Copying srr file $srr_file into $dst_srr..."
363 file copy -force $srr_file $dst_srr
367 Msg Info "Copying synth txt files $stxt_files into $dst_rpt..."
368 file copy -force {*}$stxt_files $dst_rpt
369 Msg Info "Copying synth csv files $scsv_files into $dst_rpt..."
370 file copy -force {*}$scsv_files $dst_rpt
371 Msg Info "Copying synth log files $slog_files into $dst_rpt..."
372 file copy -force {*}$slog_files $dst_rpt
373 Msg Info "Copying synth rpt files $srpt_files into $dst_rpt..."
374 file copy -force {*}$srpt_files $dst_rpt
376 Msg Info "Copying impl txt files $dtxt_files into $dst_rpt..."
377 file copy -force {*}$dtxt_files $dst_rpt
378 Msg Info "Copying impl csv files $dcsv_files into $dst_rpt..."
379 file copy -force {*}$dcsv_files $dst_rpt
380 Msg Info "Copying impl log files $dlog_files into $dst_rpt..."
381 file copy -force {*}$dlog_files $dst_rpt
382 Msg Info "Copying impl rpt files $drpt_files into $dst_rpt..."
383 file copy -force {*}$drpt_files $dst_rpt
385 set dst_main [
file normalize "$dst_dir/$proj_name\-$describe.bit"]
386 Msg Info "Copying main binary file $main_file.bit into $dst_main..."
387 file copy -force $main_file.bit $dst_main
388 Msg Info "Copying binary generation log $main_file.bgn into $dst_dir/reports..."
389 file copy -force $main_file.bgn $dst_dir/reports
391 Msg CriticalWarning "Firmware binary file not found."
396 if {[
file exists $xml_dir]} {
397 Msg Info "XML directory found, copying xml files from $xml_dir to $dst_xml..."
398 if {[
file exists $dst_xml]} {
399 Msg Info "Directory $dst_xml exists, deleting it..."
400 file delete -force $dst_xml
402 file copy -force $xml_dir $dst_xml
408 set export_xsa "NONE"
409 set part [get_property part [current_project]]
413 if {[dict exists $properties "hog"]} {
414 set propDict [dict get $properties "hog"]
415 if {[dict exists $propDict "EXPORT_XSA"]} {
416 set export_xsa [dict get $propDict "EXPORT_XSA"]
420 if {$export_xsa == "NONE"} {
423 Msg Info "SoC FPGA detected (Zynq or Versal), automatically enabling XSA file creation. \
424 To disable it, add 'EXPORT_XSA = false' in the \[hog\] section of hog.conf."
431 dict for {app_name app_conf} $apps {
433 [dict exists $app_conf "proc"] &&
434 [regexp -nocase {microblaze|risc} [dict get $app_conf "proc"]]
436 Msg Info "Soft processor ([dict get $app_conf proc]) detected in app '$app_name', \
437 automatically enabling XSA file creation. \
438 To disable it, add 'EXPORT_XSA = false' in the \[hog\] section of hog.conf."
446 if {[
string compare [
string tolower $export_xsa] "true"] == 0} {
451 regexp -- {Vivado v([0-9]{4}\.[0-9,A-z,_,\.]*) } [version] -> VIVADO_VERSION
452 if {[
string compare "2020.1" $VIVADO_VERSION] == 0} {
453 Msg Warning "Vivado 2020.1, a patch must be applied to Vivado to export XSA Files, c.f. https://www.xilinx.com/support/answers/75210.html"
455 set dst_xsa [
file normalize "$dst_dir/${proj_name}\-$describe.xsa"]
456 Msg Info "Generating XSA File at $dst_xsa"
460 set user_pre_platform_file "./Top/$group_name/$proj_name/pre-platform.tcl"
461 if {[
file exists $user_pre_platform_file]} {
462 Msg Info "Sourcing user pre-platform file $user_pre_platform_file"
463 source $user_pre_platform_file
467 if {$secondary_file == ""} {
468 set pdi_post_imp [
file normalize "$work_path/$top_name.pdi"]
469 set_property platform.full_pdi_file $pdi_post_imp [current_project]
470 Msg Info "XSA file will be generated for Versal with this PDI: $pdi_post_imp"
474 Msg Warning "No XSA will be produced in post-bitream for segmented configuration mode. \
475 If you're running with the GUI, please type the following on the Tcl console: write_hw_platform -fixed -force -file $dst_xsa."
479 "-include_bit -fixed -force -file {$dst_xsa}"
484 if {$wrote_xsa == 1} {
486 set conf_file [
lindex [
GetConfFiles $repo_path/Top/$group_name/$proj_name] 0]
487 set is_vitis_classic 0
488 set is_vitis_unified 0
490 if {[
file exists $conf_file]} {
492 set ide_name [
string tolower [
lindex $ide_name_and_ver 0]]
493 if {[
string match "*vitis_classic*" $ide_name] || [
string match "*vivado_vitis_classic*" $ide_name]} {
494 set is_vitis_classic 1
495 }
elseif {[
string match "*vitis_unified*" $ide_name] || [
string match "*vivado_vitis_unified*" $ide_name]} {
496 set is_vitis_unified 1
500 if {$is_vitis_classic || $is_vitis_unified} {
501 Msg Info "XSA file written to $dst_xsa"
503 set full_proj_name [
file join $group_name $proj_name]
506 if {$is_vitis_classic} {
507 set vitis_cmd "xsct $tcl_path/launch.tcl CW -xsa $dst_xsa -vitis_only $full_proj_name"
508 set vitis_type "Vitis Classic"
509 set error_prefix "xsct (vitis classic)"
510 }
elseif {$is_vitis_unified} {
511 set vitis_cmd "$tcl_path/launch.tcl CW -xsa $dst_xsa -vitis_only $full_proj_name"
512 set vitis_type "Vitis Unified"
513 set error_prefix "vivado (for vitis unified)"
515 Msg Error "No Vitis project type found."
519 Msg Info "Running $vitis_type to create elf file with cmd: $vitis_cmd"
520 set ret [
catch {
exec -ignorestderr {*}$vitis_cmd >@ stdout} result]
522 Msg Error "$error_prefix returned an error state."
529 foreach prop_key [dict keys $properties] {
530 if {[regexp {^app:(.+)$} $prop_key -> raw_app_name]} {
531 lappend app_names [
string trim $raw_app_name]
534 foreach app_name $app_names {
535 if {$is_vitis_unified} {
536 set elf_src [
file normalize "$repo_path/Projects/$full_proj_name/vitis_unified/$app_name/build/$app_name.elf"]
538 set elf_src [
file normalize "$repo_path/Projects/$full_proj_name/vitis_classic/$app_name/Release/$app_name.elf"]
540 set elf_dst [
file normalize "$dst_dir/${proj_name}\-${app_name}\-$describe.elf"]
541 if {[
file exists $elf_src]} {
542 Msg Info "Copying ELF $elf_src into $elf_dst..."
543 file copy -force $elf_src $elf_dst
545 Msg Warning "ELF file not found: $elf_src"
550 set mmi_file [
file normalize "$dst_dir/${proj_name}\-$describe.mmi"]
551 GenerateBootArtifacts $properties $repo_path $proj_dir $dst_dir $proj_name $describe $dst_main $mmi_file
559 set user_post_bitstream_file "./Top/$group_name/$proj_name/post-bitstream.tcl"
560 if {[
file exists $user_post_bitstream_file]} {
561 Msg Info "Sourcing user post-bitstream file $user_post_bitstream_file"
562 source $user_post_bitstream_file
565 Notify Info "Completed bitstream of $proj_name."