30 namespace eval globalSettings {
43 variable LIBERO_MANDATORY_VARIABLES
48 variable HOG_EXTERNAL_PATH
50 variable TARGET_SIMULATOR
52 variable pre_synth_file
53 variable post_synth_file
54 variable pre_impl_file
55 variable post_impl_file
57 variable post_bit_file
58 variable quartus_post_module_file
66 variable synth_top_module
69 variable vitis_classic
70 variable vitis_unified
77 variable quartus_post_module
81 proc InitProject {{vitis_only 0}} {
83 if {[
file exists $globalSettings::build_dir/vitis_classic]} {
84 file delete -force $globalSettings::build_dir/vitis_classic
86 setws $globalSettings::build_dir/vitis_classic
88 if {[
file exists $globalSettings::build_dir/vitis_unified]} {
89 file delete -force $globalSettings::build_dir/vitis_unified
91 file mkdir $globalSettings::build_dir/vitis_unified
96 set_msg_config -suppress -regexp -string {".*The IP file '.*' has been moved from its original location, as a result the outputs for this IP will now be generated in '.*'. Alternatively a copy of the IP can be imported into the project using one of the 'import_ip' or 'import_files' commands..*"}
97 set_msg_config -suppress -regexp -string {".*File '.*.xci' referenced by design '.*' could not be found..*"}
100 set_msg_config -suppress -id {IP_Flow 19-3664}
103 set_msg_config -suppress -id {Vivado 12-23660} -string {{ERROR: [Vivado 12-23660] Simulation is not supported for the target language VHDL when design contains NoC (Network-on-Chip) blocks} }
106 create_project -force [
file tail $globalSettings::DESIGN] $globalSettings::build_dir -part $globalSettings::PART
107 file mkdir "$globalSettings::build_dir/[
file tail $globalSettings::DESIGN].gen/sources_1"
108 if {[
IsVersal $globalSettings::PART]} {
109 Msg Info "This project uses a Versal device."
113 set obj [get_projects [
file tail $globalSettings::DESIGN]]
114 set_property "target_language" "VHDL" $obj
117 set_property "simulator_language" "Mixed" $obj
119 set_property "compxlib.${simulator}_compiled_library_dir" $globalSettings::simlib_path $obj
121 set_property "default_lib" "xil_defaultlib" $obj
123 set_param project.enableVHDL2008 1
124 set_property "enable_vhdl_2008" 1 $obj
126 set_property source_mgmt_mode All [current_project]
128 Msg Debug "Setting PART = $globalSettings::PART"
129 set_property PART $globalSettings::PART [current_project]
134 package require ::quartus::project
136 if {[
string equal $globalSettings::FAMILY "quartus_only"]} {
137 Msg Error "You must specify a device Family for Quartus"
139 file mkdir $globalSettings::build_dir
140 cd $globalSettings::build_dir
141 if {[is_project_open]} {
145 file delete {*}[glob -nocomplain $globalSettings::DESIGN.q*]
147 project_new -family $globalSettings::FAMILY -overwrite -part $globalSettings::PART $globalSettings::DESIGN
148 set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
153 if {[
file exists $globalSettings::build_dir]} {
154 file delete -force $globalSettings::build_dir
156 new_project -location $globalSettings::build_dir \
157 -name [
file tail $globalSettings::DESIGN] \
158 -die $globalSettings::DIE \
159 -package $globalSettings::PACKAGE \
160 -family $globalSettings::FAMILY \
163 if {[
file exists $globalSettings::build_dir]} {
164 file delete -force $globalSettings::build_dir
167 file mkdir $globalSettings::build_dir
168 cd $globalSettings::build_dir
169 prj_project new -name [
file tail $globalSettings::DESIGN] -dev $globalSettings::DEVICE -synthesis $globalSettings::SYNTHESIS_TOOL
173 puts "Creating project for $globalSettings::DESIGN part $globalSettings::PART"
174 puts "Configuring project settings:"
175 puts " - simulator_language: Mixed"
176 puts " - target_language: VHDL"
177 puts " - simulator: QuestaSim"
178 puts "Adding IP directory \"$globalSettings::user_ip_repo\" to the project "
182 proc AddProjectFiles {} {
186 if {[
string equal [get_filesets -quiet sources_1] ""]} {
187 create_fileset -srcset sources_1
189 set sources "sources_1"
201 if {[
string equal [get_filesets -quiet constrs_1] ""]} {
202 create_fileset -constrset constrs_1
206 set constraints [get_filesets constrs_1]
213 if {[
file isdirectory $globalSettings::list_path]} {
214 set list_files [glob -directory $globalSettings::list_path "*"]
216 Msg Error "No list directory found at $globalSettings::list_path"
220 source $globalSettings::tcl_path/utils/cmdline.tcl
224 AddHogFiles {*}[
GetHogFiles -list_files {.src,.sim,.ext} -ext_path $globalSettings::HOG_EXTERNAL_PATH $globalSettings::list_path $globalSettings::repo_path]
230 AddHogFiles {*}[
GetHogFiles -list_files {.con} -ext_path $globalSettings::HOG_EXTERNAL_PATH $globalSettings::list_path $globalSettings::repo_path]
244 proc CreateReportStrategy {obj} {
249 if {[
string equal [get_property -quiet report_strategy $obj] ""]} {
251 Msg Info "No report strategy needed for implementation"
254 set_property set_report_strategy_name 1 $obj
255 set_property report_strategy {Vivado Implementation Default Reports} $obj
256 set_property set_report_strategy_name 0 $obj
258 set reports [get_report_configs -of_objects $obj]
260 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_place_report_utilization_0] ""]} {
261 create_report_config -report_name impl_1_place_report_utilization_0 -report_type report_utilization:1.0 -steps place_design -runs impl_1
263 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_place_report_utilization_0]
269 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_drc_0] ""]} {
270 create_report_config -report_name impl_1_route_report_drc_0 -report_type report_drc:1.0 -steps route_design -runs impl_1
272 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_drc_0]
278 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_power_0] ""]} {
279 create_report_config -report_name impl_1_route_report_power_0 -report_type report_power:1.0 -steps route_design -runs impl_1
281 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_power_0]
287 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_timing_summary] ""]} {
288 create_report_config -report_name impl_1_route_report_timing_summary -report_type report_timing_summary:1.0 -steps route_design -runs impl_1
290 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_timing_summary]
292 Msg Info "Report timing created successfully"
296 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_utilization] ""]} {
297 create_report_config -report_name impl_1_route_report_utilization -report_type report_utilization:1.0 -steps route_design -runs impl_1
299 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_utilization]
301 Msg Info "Report utilization created successfully"
306 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_post_route_phys_opt_report_timing_summary_0] ""]} {
307 create_report_config -report_name impl_1_post_route_phys_opt_report_timing_summary_0 \
308 -report_type report_timing_summary:1.0 \
309 -steps post_route_phys_opt_design -runs impl_1
311 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_post_route_phys_opt_report_timing_summary_0]
313 set_property -name "options.max_paths" -value "10" -objects $obj
314 set_property -name "options.warn_on_violation" -value "1" -objects $obj
318 Msg Info "Won't create any report strategy, not in Vivado"
328 proc ConfigureSynthesis {} {
332 if {[
string equal [get_runs -quiet synth_1] ""]} {
333 create_run -name synth_1 -part $globalSettings::PART -constrset constrs_1
338 set obj [get_runs synth_1]
339 set_property "part" $globalSettings::PART $obj
343 if {$globalSettings::pre_synth_file ne ""} {
347 if {[get_filesets -quiet utils_1] != ""} {
348 AddFile $globalSettings::pre_synth [get_filesets -quiet utils_1]
350 set_property STEPS.SYNTH_DESIGN.TCL.PRE $globalSettings::pre_synth $obj
354 set_global_assignment -name PRE_FLOW_SCRIPT_FILE quartus_sh:$globalSettings::pre_synth
356 configure_tool -name {SYNTHESIZE} -params SYNPLIFY_TCL_FILE:$globalSettings::pre_synth
358 prj_impl pre_script "syn" $globalSettings::pre_synth
361 Msg Debug "Setting $globalSettings::pre_synth to be run before synthesis"
365 if {$globalSettings::post_synth_file ne ""} {
369 if {[get_filesets -quiet utils_1] != ""} {
370 AddFile $globalSettings::post_synth [get_filesets -quiet utils_1]
372 set_property STEPS.SYNTH_DESIGN.TCL.POST $globalSettings::post_synth $obj
376 set_global_assignment -name POST_MODULE_SCRIPT_FILE quartus_sh:$globalSettings::quartus_post_module
378 prj_impl post_script "syn" $globalSettings::post_synth
380 Msg Debug "Setting $globalSettings::post_synth to be run after synthesis"
387 current_run -synthesis $obj
390 if {[
string equal [get_property -quiet report_strategy $obj] ""]} {
392 Msg Debug "No report strategy needed for synthesis"
395 set_property set_report_strategy_name 1 $obj
396 set_property report_strategy {Vivado Synthesis Default Reports} $obj
397 set_property set_report_strategy_name 0 $obj
399 if {[
string equal [get_report_configs -of_objects [get_runs synth_1] synth_1_synth_report_utilization_0] ""]} {
400 create_report_config -report_name synth_1_synth_report_utilization_0 -report_type report_utilization:1.0 -steps synth_design -runs synth_1
402 set reports [get_report_configs -of_objects [get_runs synth_1] synth_1_synth_report_utilization_0]
412 Msg info "Reporting strategy for synthesis"
421 proc ConfigureImplementation {} {
425 if {[
string equal [get_runs -quiet impl_1] ""]} {
426 create_run -name impl_1 -part $globalSettings::PART -constrset constrs_1 -parent_run synth_1
429 set obj [get_runs impl_1]
430 set_property "part" $globalSettings::PART $obj
432 set_property "steps.[
BinaryStepName $globalSettings::PART].args.readback_file" "0" $obj
433 set_property "steps.[
BinaryStepName $globalSettings::PART].args.verbose" "0" $obj
441 if {$globalSettings::pre_impl_file ne ""} {
445 if {[get_filesets -quiet utils_1] != ""} {
446 AddFile $globalSettings::pre_impl [get_filesets -quiet utils_1]
448 set_property STEPS.INIT_DESIGN.TCL.POST $globalSettings::pre_impl $obj
454 prj_impl pre_script "par" $globalSettings::pre_impl
456 Msg Debug "Setting $globalSettings::pre_impl to be run after implementation"
461 if {$globalSettings::post_impl_file ne ""} {
465 if {[get_filesets -quiet utils_1] != ""} {
466 AddFile $globalSettings::post_impl [get_filesets -quiet utils_1]
468 set_property STEPS.ROUTE_DESIGN.TCL.POST $globalSettings::post_impl $obj
472 set_global_assignment -name POST_MODULE_SCRIPT_FILE quartus_sh:$globalSettings::quartus_post_module
474 prj_impl post_script "par" $globalSettings::post_impl
476 Msg Debug "Setting $globalSettings::post_impl to be run after implementation"
480 if {$globalSettings::pre_bit_file ne ""} {
484 if {[get_filesets -quiet utils_1] != ""} {
485 AddFile $globalSettings::pre_bit [get_filesets -quiet utils_1]
487 set_property STEPS.[
BinaryStepName $globalSettings::PART].TCL.PRE $globalSettings::pre_bit $obj
493 prj_impl pre_script "export" $globalSettings::pre_bit
495 Msg Debug "Setting $globalSettings::pre_bit to be run after bitfile generation"
499 if {$globalSettings::post_bit_file ne ""} {
503 if {[get_filesets -quiet utils_1] != ""} {
504 AddFile $globalSettings::post_bit [get_filesets -quiet utils_1]
506 set_property STEPS.[
BinaryStepName $globalSettings::PART].TCL.POST $globalSettings::post_bit $obj
510 set_global_assignment -name POST_MODULE_SCRIPT_FILE quartus_sh:$globalSettings::quartus_post_module
512 prj_impl post_script "export" $globalSettings::post_bit
514 Msg Debug "Setting $globalSettings::post_bit to be run after bitfile generation"
523 proc ConfigureSimulation {} {
524 set simsets_dict [
GetSimSets "$globalSettings::group_name/$globalSettings::DESIGN" $globalSettings::repo_path]
530 Msg Debug "Setting load_glbl parameter to true for every fileset..."
531 foreach simset [get_filesets -quiet] {
532 if {[get_property FILESET_TYPE $simset] != "SimulationSrcs"} {
536 set_property -name {xsim.elaborate.load_glbl} -value {true} -objects [get_filesets $simset]
539 set sim_dict [
DictGet $simsets_dict $simset]
540 set sim_props [
DictGet $sim_dict "properties"]
542 if {$sim_props != ""} {
543 Msg Info "Setting properties for simulation set: $simset..."
544 dict for {prop_name prop_val} $sim_props {
545 set prop_name [string toupper $prop_name]
546 if {$prop_name == "ACTIVE" && $prop_val == 1} {
547 Msg Info "Setting $simset as active simulation set..."
548 current_fileset -simset [get_filesets $simset]
550 Msg Debug "Setting $prop_name = $prop_val"
551 if {[IsInList [string toupper $prop_name] [VIVADO_PATH_PROPERTIES] 1]} {
552 # Check that the file exists before setting these properties
553 if {[file exists $globalSettings::repo_path/$prop_val]} {
554 set_property -name $prop_name -value $globalSettings::repo_path/$prop_val -objects [get_filesets $simset]
556 Msg Warning "Impossible to set property $prop_name to $prop_val. File is missing"
559 set_property -name $prop_name -value $prop_val -objects [get_filesets $simset]
570 proc ConfigureProperties {} {
572 cd $globalSettings::repo_path
576 if {[
info exists globalSettings::PROPERTIES]} {
577 if {[dict exists $globalSettings::PROPERTIES main]} {
578 Msg Info "Setting project-wide properties..."
579 set proj_props [dict get $globalSettings::PROPERTIES main]
580 dict for {prop_name prop_val} $proj_props {
581 if {[string tolower $prop_name] != "ip_repo_paths"} {
582 if {[string tolower $prop_name] != "part"} {
583 # Part is already set
584 Msg Debug "Setting $prop_name = $prop_val"
585 set_property -name $prop_name -value $prop_val -objects [current_project]
588 set ip_repo_list [regsub -all {\s+} $prop_val " $globalSettings::repo_path/"]
589 set ip_repo_list $globalSettings::repo_path/$ip_repo_list
591 Msg Info "Setting $ip_repo_list as user IP repository..."
593 set_property ip_repo_paths "$ip_repo_list" [current_fileset]
595 set_property ip_repo_paths "$ip_repo_list" [current_project]
602 foreach run [get_runs -quiet] {
603 if {[dict exists $globalSettings::PROPERTIES $run]} {
604 Msg Info "Setting properties for run: $run..."
605 set run_props [dict get $globalSettings::PROPERTIES $run]
607 set stragety_str "STRATEGY strategy Strategy"
608 Msg Debug "Setting Strategy and Flow for run $run (if specified in hog.conf)"
609 foreach s $stragety_str {
610 if {[dict exists $run_props $s]} {
611 set prop [dict get $run_props $s]
612 set_property -name $s -value $prop -objects $run
613 set run_props [dict remove $run_props $s]
614 Msg Warning "A strategy for run $run has been defined inside hog.conf. This prevents Hog to compare the project properties. \
615 Please regenerate your hog.conf file using the dedicated Hog button."
616 Msg Info "Setting $s = $prop"
620 dict for {prop_name prop_val} $run_props {
621 Msg Debug "Setting $prop_name = $prop_val"
622 if {[string trim $prop_val] == ""} {
623 Msg Warning "Property $prop_name has empty value. Skipping..."
626 if {[IsInList [string toupper $prop_name] [VIVADO_PATH_PROPERTIES] 1]} {
627 # Check that the file exists before setting these properties
628 set utility_file $globalSettings::repo_path/$prop_val
629 if {[file exists $utility_file]} {
630 lassign [GetHogFiles -ext_path $globalSettings::HOG_EXTERNAL_PATH $globalSettings::list_path $globalSettings::repo_path] lib prop dummy
633 lappend hog_files $ff
636 if {[lsearch $hog_files $utility_file] < 0} {
637 Msg CriticalWarning "The file: $utility_file is set as a property in hog.conf, \
638 but is not added to the project in any list file. Hog cannot track it."
640 #Add file tu utils_1 to avoid warning
641 AddFile $globalSettings::repo_path/$prop_val [get_filesets -quiet utils_1]
643 set_property -name $prop_name -value $utility_file -objects $run
645 Msg Warning "Impossible to set property $prop_name to $prop_val. File is missing"
648 set_property -name $prop_name -value $prop_val -objects $run
659 if {[
info exists globalSettings::PROPERTIES]} {
661 if {[dict exists $globalSettings::PROPERTIES main]} {
662 Msg Info "Setting device properties..."
663 set dev_props [dict get $globalSettings::PROPERTIES main]
664 dict for {prop_name prop_val} $dev_props {
665 if {!([string toupper $prop_name] in $globalSettings::LIBERO_MANDATORY_VARIABLES)} {
666 Msg Debug "Setting $prop_name = $prop_val"
667 set_device -[string tolower $prop_name] $prop_val
672 if {[dict exists $globalSettings::PROPERTIES project]} {
673 Msg Info "Setting project-wide properties..."
674 set dev_props [dict get $globalSettings::PROPERTIES project]
675 dict for {prop_name prop_val} $dev_props {
676 Msg Debug "Setting $prop_name = $prop_val"
677 project_settings -[string tolower $prop_name] $prop_val
681 if {[dict exists $globalSettings::PROPERTIES synth]} {
682 Msg Info "Setting Synthesis properties..."
683 set synth_props [dict get $globalSettings::PROPERTIES synth]
684 dict for {prop_name prop_val} $synth_props {
685 Msg Debug "Setting $prop_name = $prop_val"
686 configure_tool -name {SYNTHESIZE} -params "[string toupper $prop_name]:$prop_val"
690 if {[dict exists $globalSettings::PROPERTIES impl]} {
691 Msg Info "Setting Implementation properties..."
692 set impl_props [dict get $globalSettings::PROPERTIES impl]
693 dict for {prop_name prop_val} $impl_props {
694 Msg Debug "Setting $prop_name = $prop_val"
695 configure_tool -name {PLACEROUTE} -params "[string toupper $prop_name]:$prop_val"
700 if {[dict exists $globalSettings::PROPERTIES bitstream]} {
701 Msg Info "Setting Bitstream properties..."
702 set impl_props [dict get $globalSettings::PROPERTIES impl]
703 dict for {prop_name prop_val} $impl_props {
704 Msg Debug "Setting $prop_name = $prop_val"
705 configure_tool -name {GENERATEPROGRAMMINGFILE} -params "[string toupper $prop_name]:$prop_val"
709 configure_tool -name {VERIFYTIMING} -params {FORMAT:TEXT}
712 if {[
info exists globalSettings::PROPERTIES]} {
714 if {[dict exists $globalSettings::PROPERTIES main]} {
715 Msg Info "Setting project-wide properties..."
716 set dev_props [dict get $globalSettings::PROPERTIES main]
717 dict for {prop_name prop_val} $dev_props {
718 # Device is already set
719 if {[string toupper $prop_name] != "DEVICE"} {
720 Msg Debug "Setting $prop_name = $prop_val"
721 prj_project option $prop_name $prop_val
726 if {[dict exists $globalSettings::PROPERTIES impl]} {
727 Msg Info "Setting Implementation properties..."
728 set dev_props [dict get $globalSettings::PROPERTIES impl]
729 dict for {prop_name prop_val} $dev_props {
730 # Device is already set
731 Msg Debug "Setting $prop_name = $prop_val"
732 prj_impl option $prop_name $prop_val
737 Msg info "Configuring Properties"
743 proc ConfigurePlatforms {{xsa ""}} {
744 dict for {key value} [dict filter $globalSettings::PROPERTIES key {platform:*}] {
745 set value_lower [dict create]
746 dict for {vkey vvalue} $value {
747 dict set value_lower [string tolower $vkey] $vvalue
749 dict set platforms $key $value_lower
755 dict for {key value} $platforms2 {
756 Msg Info "Key: $key, Value: $value"
759 if {[dict size $platforms] == 0} {
760 Msg Info "No platforms found in the configuration file"
764 dict for {platform_key platform_config} $platforms {
765 Msg Info "Found platform with key: $platform_key with configuration: $platform_config"
766 if {[regexp {^platform:(.+)$} $platform_key -> platform_name]} {
767 set platform_name [string trim $platform_name]
768 Msg Info "Configuring platform: $platform_name"
769 CreatePlatform $platform_name $platform_config $xsa
771 Msg Warning "Invalid platform key format: $platform_key. Expected format: platform:<name>"
776 proc CreatePlatform {platform_name platform_conf {xsa ""}} {
778 set platform_create_options {
779 "desc" "hw" "out" "prebuilt" "proc" "arch"
780 "samples" "os" "xpfm" "no-boot-bsp"
783 Msg Info "Creating platform configuration..."
784 append platform_options " -name $platform_name"
787 if {[
catch {
set ws_platforms [platform list -dict]}]} {
set ws_platforms ""}
788 if {[lsearch -exact $ws_platforms $platform_name] != -1} {
789 Msg Info "Platform $platform_name already exists, removing it..."
790 platform remove $platform_name
793 dict for {p v} $platform_conf {
794 if {[IsInList [string toupper $p] [VITIS_PATH_PROPERTIES] 1]} {
796 if {[IsRelativePath $v] == 1} {
797 set v "$globalSettings::repo_path/$v"
800 if {[file exists $v]} {
805 Msg Warning "Impossible to set property $p to $v. File is missing"
810 set p_lower [string tolower $p]
811 if {[IsInList $p_lower $platform_create_options]} {
812 append platform_options " -$p_lower $v"
814 if {$p_lower ne "bif"} {
815 Msg Warning "Attempting to use unknown platform option: $p_lower"
816 append platform_options " -$p_lower $v"
824 set platform_options "$platform_options -hw $xsa"
825 }
elseif {![dict exists $platform_conf hw]} {
826 set xsa "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"
827 set platform_options "$platform_options -hw $xsa"
829 set platform_options "$platform_options"
834 Msg Info "Opening hardware design to check if proc to cell mapping needs to be extracted for soft processors..."
836 hsi::open_hw_design $xsa
837 set proc_cells [hsi::get_cells -filter { IP_TYPE == "PROCESSOR" }]
838 set proc_map_file [open "$globalSettings::build_dir/vitis_classic/$platform_name.PROC_MAP" "w"]
840 foreach proc $proc_cells {
842 Msg Debug "Processor found in xsa: $proc"
843 if {[regexp -nocase {microblaze|risc} $proc]} {
844 Msg Info "Extracting processor cells for soft processor: $proc"
845 set proc_hier_name [hsi::get_property HIER_NAME $proc]
846 set proc_address_tag [hsi::get_property ADDRESS_TAG $proc]
848 if {$proc_address_tag eq ""} {
849 Msg Warning "Processor $proc ($proc_hier_name) does not have an ADDRESS_TAG property set. \
850 This may cause issues when configuring the platform."
852 set proc_map_entry "$proc_hier_name $proc_address_tag"
853 puts $proc_map_file "$proc_map_entry\n"
858 hsi::close_hw_design [hsi::current_hw_design]
863 Msg Info "Creating platform \[$platform_name\] with options: \{$platform_options\}"
865 set plat_create "platform create $platform_options"
867 platform active $platform_name
871 set python_script "$globalSettings::repo_path/Hog/Other/Python/VitisUnified/PlatformCommands.py"
872 Msg Info "Running Vitis Unified platform creation script..."
873 set platform_options_str "{ $platform_options }"
874 set error_msg "Failed to create platform $platform_name"
876 [list $platform_options_str "$globalSettings::build_dir/vitis_unified"] \
884 proc ConfigureApps {} {
885 set apps [dict filter $globalSettings::PROPERTIES key {app:*}]
887 if {[dict size $apps] == 0} {
888 Msg Info "No apps found in the configuration file"
892 dict for {app_key app_config} $apps {
893 Msg Info "Found app with key: $app_key with configuration: $app_config"
894 if {[regexp {^app:(.+)$} $app_key -> app_name]} {
895 set app_name [string trim $app_name]
896 Msg Info "Configuring app: $app_name"
897 if {[IsVitisClassic]} {
898 ConfigureApp $app_name $app_config
899 } elseif {[IsVitisUnified]} {
900 set python_script "$globalSettings::repo_path/Hog/Other/Python/VitisUnified/AppCommands.py"
901 Msg Info "Running Vitis Unified app configuration script..."
902 # Build app config string from app_config dict
903 set app_config_str "{"
904 dict for {p v} $app_config {
905 append app_config_str " -[string toupper $p] \{$v\}"
907 append app_config_str " }"
908 set error_msg "Failed to configure app $app_name"
909 if {![ExecuteVitisUnifiedCommand $python_script "configure_app" \
910 [list $app_name $app_config_str "$globalSettings::build_dir/vitis_unified"] \
916 Msg Warning "Invalid app key format: $app_key. Expected format: app:<name>"
921 proc ConfigureApp {app_name app_conf} {
924 "platform" "domain" "sysproj" "hw"
925 "proc" "template" "os" "lang" "arch" "name"
929 "assembler-flags" "build-config" "compiler-misc" "compiler-optimization"
930 "define-compiler-symbols" "include-path" "libraries" "library-search-path"
931 "linker-misc" "linker-script" "undef-compiler-symbols"
934 Msg Info "Configuring app..."
935 append app_options " -name $app_name"
938 if {[
catch {
set sys_projs [sysproj list -dict]}]} {
set sys_projs ""}
939 if {[dict exists $app_name sysproj]} {
940 set sys_proj_name [dict get $app_name sysproj]
941 if {[lsearch -exact $sys_projs "Name $sys_proj_name"] != -1} {
942 Msg Info "Removing $sys_proj_name..."
943 sysproj remove $sys_proj_name
946 set sys_proj_name "$app_name\_system"
947 if {[lsearch -exact $sys_projs "Name $sys_proj_name"] != -1} {
948 Msg Info "Removing $sys_proj_name..."
949 sysproj remove $sys_proj_name
954 if {[
catch {
set ws_apps [app list -dict]}]} {
set ws_apps ""}
955 if {[lsearch -exact $ws_apps $app_name] != -1} {
956 Msg Info "app $app_name already exists, removing it..."
960 set app_create_options [dict create]
961 set app_conf_options [dict create]
964 dict for {p v} $app_conf {
965 set p_lower [string tolower $p]
967 if {[IsInList [string toupper $p] [VITIS_PATH_PROPERTIES] 1]} {
968 if {[IsRelativePath $v] == 1} {
969 set v "$globalSettings::repo_path/$v"
972 if {![file exists $v]} {
973 Msg Warning "Impossible to set property $p to $v. File is missing"
978 if {[IsInList $p_lower $create_options]} {
979 Msg Info "$p_lower is in create options"
980 dict append app_create_options $p_lower $v
981 } elseif {[IsInList $p_lower $conf_options]} {
982 Msg Info "$p_lower is in conf options"
983 dict append app_conf_options $p_lower $v
985 Msg Warning "Unknown app option: $p_lower"
990 dict for {p v} $app_create_options {
991 if {[string equal $p "platform"]} {
992 Msg Info "Setting App $app_name platform to $v"
995 append app_options " -$p $v"
998 if {![dict exists $app_name template]} {
1001 if {[dict exists $app_create_options "lang"]} {
1002 set lang [dict get $app_create_options "lang"]
1003 if {[
string equal -nocase $lang "C++"] || [
string equal -nocase $lang "cpp"]} {
1004 append app_options " -template \{Empty Application (C++)\}"
1006 append app_options " -template \{Empty Application(C)\}"
1010 append app_options " -template \{Empty Application(C)\}"
1014 append app_options " -template \{Empty Application\}"
1018 Msg Info "Creating application \[$app_name\] with options: \{$app_options\}"
1019 set app_create "app create $app_options"
1021 app config -name $app_name -set build-config Release
1024 dict for {p v} $app_conf_options {
1025 Msg Info "Configuring app option $p to $v"
1026 app config -name $app_name -set $p $v
1031 proc AddAppFiles {} {
1032 AddHogFiles {*}[
GetHogFiles -list_files {.src,.header} -ext_path $globalSettings::HOG_EXTERNAL_PATH $globalSettings::list_path $globalSettings::repo_path]
1045 proc ConfigureHlsComponents {} {
1046 set hls_components [dict filter $globalSettings::PROPERTIES key {hls:*}]
1048 if {[dict size $hls_components] == 0} {
1049 Msg Info "No HLS components found in the configuration file"
1053 set python_script "$globalSettings::repo_path/Hog/Other/Python/VitisUnified/HlsCommands.py"
1054 set ws_dir [
file normalize "$globalSettings::build_dir/vitis_unified"]
1056 dict for {hls_key hls_config} $hls_components {
1057 if {[regexp {^hls:(.+)$} $hls_key -> component_name]} {
1058 set component_name [string trim $component_name]
1059 Msg Info "Configuring HLS component: $component_name"
1061 # Get HLS_CONFIG path from hog.conf (mandatory)
1063 if {[dict exists $hls_config hls_config]} {
1064 set hls_cfg_rel [dict get $hls_config hls_config]
1065 } elseif {[dict exists $hls_config HLS_CONFIG]} {
1066 set hls_cfg_rel [dict get $hls_config HLS_CONFIG]
1068 if {$hls_cfg_rel eq ""} {
1069 Msg Error "HLS component '$component_name' missing HLS_CONFIG in hog.conf \[hls:$component_name\] section"
1073 set hls_cfg_file [file normalize "$globalSettings::repo_path/$hls_cfg_rel"]
1074 if {![file exists $hls_cfg_file]} {
1075 Msg Error "HLS config file not found: $hls_cfg_file (from HLS_CONFIG=$hls_cfg_rel)"
1079 Msg Info " HLS config: $hls_cfg_file"
1081 # Validate the config file
1082 set error_msg "Failed to validate HLS config for $component_name"
1083 if {![ExecuteVitisUnifiedCommand $python_script "validate" \
1084 [list $hls_cfg_file] \
1086 Msg Error $error_msg
1090 # Create Vitis workspace with HLS component for GUI compatibility
1091 set hls_work_dir [file normalize "$ws_dir/hls_$component_name"]
1092 Msg Info "Creating Vitis HLS workspace component '$component_name' in $ws_dir ..."
1093 if {![ExecuteVitisUnifiedCommand $python_script "create_workspace" \
1094 [list $ws_dir $component_name $hls_cfg_file $hls_work_dir] \
1095 "Failed to create HLS workspace for $component_name"]} {
1096 Msg Warning "Could not create Vitis workspace for HLS component '$component_name'"
1099 Msg Info "HLS component '$component_name' configured successfully"
1101 Msg Warning "Invalid HLS key format: $hls_key. Expected format: hls:<name>"
1110 current_run -implementation [get_runs impl_1]
1117 Msg Info "Running report_ip_status, before upgrading and handling IPs..."
1120 if {$globalSettings::HOG_IP_PATH != ""} {
1121 set ip_repo_path $globalSettings::HOG_IP_PATH
1122 Msg Info "HOG_IP_PATH is set, will pull/push synthesised IPs from/to $ip_repo_path."
1124 HandleIP pull [get_property IP_FILE $ip] $ip_repo_path $globalSettings::repo_path [get_property IP_OUTPUT_DIR $ip]
1127 Msg Info "HOG_IP_PATH not set, will not push/pull synthesised IPs."
1131 proc SetGlobalVar {var {default_value HOG_NONE}} {
1133 if {[
info exists ::$var]} {
1134 Msg Debug "Setting $var to [subst $[subst ::$var]]"
1136 set globalSettings::$var [subst $[subst ::$var]]
1137 }
elseif {$default_value == "HOG_NONE"} {
1138 Msg Error "Mandatory variable $var was not defined. Please define it in hog.conf or in project tcl script."
1140 Msg Info "Setting $var to default value: \"$default_value\""
1142 set globalSettings::$var $default_value
1148 proc CreateProject {args} {
1153 if {[
catch {
package require cmdline} ERROR]} {
1154 puts "ERROR: If you are running this script on tclsh, you can fix this by installing 'tcllib'"
1158 {simlib_path.arg "" "Path of simulation libs"}
1159 {verbose "If set, launch the script in verbose mode."}
1160 {xsa.arg "" "xsa for creating platforms without a defined hw."}
1161 {vivado_only "If set, and project is vivado-vitis, vitis project will not be created."}
1162 {vitis_only "If set, and project is vivado-vitis, only vitis project will be created."}
1165 set usage "Create Vivado/Vitis/ISE/Quartus/Libero/Diamond project.\nUsage: CreateProject \[OPTIONS\] <project> <repository path>\n Options:"
1167 if {[
catch {
array set options [
cmdline::getoptions args $parameters $usage]}] || [
llength $args] < 2 || [
lindex $args 0] eq ""} {
1172 set globalSettings::DESIGN [
lindex $args 0]
1173 if {[
file exists [
lindex $args 1]]} {
1174 set globalSettings::repo_path [
file normalize [
lindex $args 1]]
1176 Msg Error "The second argument, [
lindex $args 1], should be the repository path."
1178 set globalSettings::tcl_path $globalSettings::repo_path/Hog/Tcl
1181 if {$options(verbose) == 1} {
1182 variable ::DEBUG_MODE 1
1186 if {$options(simlib_path) != ""} {
1188 set globalSettings::simlib_path "$options(simlib_path)"
1190 set globalSettings::simlib_path "${globalSettings::repo_path}/$options(simlib_path)"
1192 Msg Info "Simulation library path set to $options(simlib_path)"
1194 set globalSettings::simlib_path "${globalSettings::repo_path}/SimulationLib"
1195 Msg Info "Simulation library path set to default ${globalSettings::repo_path}/SimulationLib"
1201 set build_dir_name "Projects"
1202 set globalSettings::group_name [
file dirname ${globalSettings::DESIGN}]
1203 set globalSettings::project_name ${globalSettings::DESIGN}
1204 set globalSettings::pre_synth_file "pre-synthesis.tcl"
1205 set globalSettings::post_synth_file "post-synthesis.tcl"
1206 set globalSettings::pre_impl_file "pre-implementation.tcl"
1207 set globalSettings::post_impl_file "post-implementation.tcl"
1208 set globalSettings::pre_bit_file "pre-bitstream.tcl"
1209 set globalSettings::post_bit_file "post-bitstream.tcl"
1210 set globalSettings::quartus_post_module_file "quartus-post-module.tcl"
1211 set globalSettings::top_path "${globalSettings::repo_path}/Top/${globalSettings::DESIGN}"
1212 set globalSettings::list_path "${globalSettings::top_path}/list"
1213 set globalSettings::build_dir "${globalSettings::repo_path}/${build_dir_name}/${globalSettings::DESIGN}"
1214 set globalSettings::DESIGN [
file tail ${globalSettings::DESIGN}]
1215 set globalSettings::top_name [
file tail ${globalSettings::DESIGN}]
1216 set globalSettings::top_name [
file rootname ${globalSettings::top_name}]
1217 set globalSettings::synth_top_module "top_${globalSettings::top_name}"
1218 set globalSettings::user_ip_repo ""
1220 set globalSettings::pre_synth [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::pre_synth_file}"]
1221 set globalSettings::post_synth [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::post_synth_file}"]
1222 set globalSettings::pre_impl [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::pre_impl_file}"]
1223 set globalSettings::post_impl [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::post_impl_file}"]
1224 set globalSettings::pre_bit [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::pre_bit_file}"]
1225 set globalSettings::post_bit [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::post_bit_file}"]
1226 set globalSettings::quartus_post_module [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::quartus_post_module_file}"]
1227 set globalSettings::LIBERO_MANDATORY_VARIABLES {"FAMILY" "PACKAGE" "DIE" }
1229 set proj_dir [
file normalize "${globalSettings::repo_path}/Top/${globalSettings::project_name}"]
1230 Msg Debug "Calling GetConfFiles with proj_dir=$proj_dir (project_name=${globalSettings::project_name})"
1231 lassign [
GetConfFiles $proj_dir] conf_file sim_file pre_file post_file pre_rtl_file
1234 if {[
file exists $conf_file]} {
1235 Msg Info "Parsing configuration file $conf_file..."
1242 if {$conf_version != "0.0.0"} {
1243 set globalSettings::a_v [
split $actual_version "."]
1244 set globalSettings::c_v [
split $conf_version "."]
1246 if {[
llength $globalSettings::a_v] < 2} {
1247 Msg Error "Couldn't parse IDE version: $actual_version."
1248 }
elseif {[
llength $globalSettings::a_v] == 2} {
1249 lappend globalSettings::a_v 0
1251 if {[
llength $globalSettings::c_v] < 2} {
1252 Msg Error "Wrong version format in hog.conf: $conf_version."
1253 }
elseif {[
llength $globalSettings::c_v] == 2} {
1254 lappend globalSettings::c_v 0
1259 Msg Info "Project version and $ide version match: $conf_version."
1260 }
elseif {$comp == 1} {
1261 Msg CriticalWarning "The $ide version in use is $actual_version, that is newer than $conf_version, as specified in the first line of $conf_file.\n\
1262 If you want update this project to version $actual_version, please update the configuration file."
1265 Msg Error "The $ide version in use is $actual_version, that is older than $conf_version as specified in $conf_file. The project will not be created.\nIf you absolutely want to create this project that was meant for version $conf_version with $ide version $actual_version, you can change the version from the first line of $conf_file.\nThis is HIGHLY discouraged as there could be unrecognised properties in the configuration file and IPs created with a newer $ide version cannot be downgraded."
1268 Msg CriticalWarning "No version found in the first line of $conf_file. \
1269 It is HIGHLY recommended to replace the first line of $conf_file with: \#$ide $actual_version"
1272 if {$globalSettings::vitis_classic == 1} {
1274 Msg Error "Vitis Classic flow is not supported for versions < 2020.2. Please use Vitis 2020.2 or newer."}
1276 if {$globalSettings::vitis_unified == 1} {
1278 Msg Error "Vitis Unified flow is not supported for versions < 2019.2. Please use Vitis 2019.2 or newer."}
1281 if {[dict exists $globalSettings::PROPERTIES main]} {
1282 set main [dict get $globalSettings::PROPERTIES main]
1283 dict for {p v} $main {
1284 # notice the dollar in front of p: creates new variables and fill them with the value
1285 Msg Info "Main property $p set to $v"
1290 Msg Error "No main section found in $conf_file, make sure it has a section called \[main\] containing the mandatory properties."
1293 Msg Error "$conf_file was not found in your project directory, please create one."
1319 if {[
info exists env(HOG_EXTERNAL_PATH)]} {
1320 set globalSettings::HOG_EXTERNAL_PATH $env(HOG_EXTERNAL_PATH)
1322 set globalSettings::HOG_EXTERNAL_PATH ""
1325 set user_hog_file "${globalSettings::repo_path}/Top/hog.tcl"
1326 if {[
file exists $user_hog_file]} {
1327 Msg Info "Sourcing user hog.tcl file..."
1328 source $user_hog_file
1331 if {[
file exists $pre_file]} {
1332 Msg Info "Found pre-creation Tcl script $pre_file, executing it..."
1336 if {[
info exists env(HOG_IP_PATH)]} {
1337 set globalSettings::HOG_IP_PATH $env(HOG_IP_PATH)
1339 set globalSettings::HOG_IP_PATH ""
1346 set has_hls [
expr {[dict size [dict filter $globalSettings::PROPERTIES key {hls:*}]] > 0}]
1347 set has_platforms [
expr {[dict size [dict filter $globalSettings::PROPERTIES key {platform:*}]] > 0}]
1348 set has_apps [
expr {[dict size [dict filter $globalSettings::PROPERTIES key {app:*}]] > 0}]
1351 Msg Info "Found HLS component(s) in configuration, configuring HLS..."
1355 if {!$has_platforms && !$has_apps} {
1356 Msg Info "vitis unified HLS-only project, skipping Vivado project setup."
1360 if {$has_platforms || $has_apps} {
1361 set xsa_path $options(xsa)
1363 if {$xsa_path == ""} {
1364 if {[
string match "vivado_*" [
string tolower $ide]]} {
1366 set xpr_file [
file normalize "$globalSettings::build_dir/[
file tail $globalSettings::DESIGN].xpr"]
1367 if {[
file exists $xpr_file]} {
1368 Msg Info "Opening existing Vivado project to generate pre-synth XSA..."
1369 open_project $xpr_file
1370 set xsa_path [
file normalize "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"]
1371 write_hw_platform -fixed -force -file $xsa_path
1372 Msg Info "Pre-synth XSA generated: $xsa_path"
1376 Msg Error "Vivado project not found at $xpr_file. Please run CREATE without -vitis_only first to create the Vivado project or provide an XSA file via the -xsa option."
1381 Msg Error "This is a $ide only project with platform/app sections, an XSA file must be provided via the -xsa option."
1386 Msg Info "Configuring platforms with XSA: $xsa_path"
1390 if {[
file exists $post_file]} {
1391 Msg Info "Found post-creation Tcl script $post_file, executing it..."
1400 if {([
string tolower $ide] eq "vitis_classic" || [
string tolower $ide] eq "vitis_unified") && $options(vitis_only) == 1} {
1401 if {$options(xsa) == ""} {
1402 Msg Error "This is a $ide only project, an XSA file must be provided via -xsa option."
1420 set fileName_old [
file normalize "./hogTmp/.hogQsys.md5"]
1421 set fileDir [
file normalize "${globalSettings::build_dir}/.hog/"]
1423 set fileName_new [
file normalize "$fileDir/.hogQsys.md5"]
1424 if {[
file exists $fileName_new]} {
1425 file delete $fileName_new
1427 if {[
file exists $fileName_old]} {
1428 file rename -force $fileName_old $fileName_new
1429 file delete -force -- "./hogTmp"
1433 if {[
file exists $post_file]} {
1434 Msg Info "Found post-creation Tcl script $post_file, executing it..."
1438 build_design_hierarchy
1445 -ext_path "$globalSettings::HOG_EXTERNAL_PATH" \
1446 -list_files ".src,.ext" \
1447 "$globalSettings::repo_path/Top/$globalSettings::project_name/list/" \
1448 $globalSettings::repo_path] \
1449 listLibraries listProperties listSrcSets
1452 -ext_path "$globalSettings::HOG_EXTERNAL_PATH" \
1453 -list_files ".con" \
1454 "$globalSettings::repo_path/Top/$globalSettings::project_name/list/" \
1455 $globalSettings::repo_path] \
1456 listConstraints listConProperties listConSets
1459 -ext_path "$globalSettings::HOG_EXTERNAL_PATH" \
1460 -list_files ".sim" \
1461 "$globalSettings::repo_path/Top/$globalSettings::project_name/list/" \
1462 $globalSettings::repo_path] \
1463 listSimLibraries listSimProperties listSimSets
1466 cd $globalSettings::build_dir
1472 cd $globalSettings::repo_path
1476 [
file normalize $globalSettings::repo_path/Top/$globalSettings::project_name] \
1477 $globalSettings::repo_path \
1478 $globalSettings::HOG_EXTERNAL_PATH
1479 ] commit version hog_hash hog_ver top_hash top_ver libs hashes vers cons_ver cons_hash ext_names ext_hashes \
1480 xml_hash xml_ver user_ip_repos user_ip_hashes user_ip_vers
1485 set commit $this_commit
1488 if {$xml_hash != ""} {
1497 $globalSettings::repo_path \
1498 $globalSettings::project_name \
1499 $date $timee $commit $version \
1500 $top_hash $top_ver $hog_hash $hog_ver \
1501 $cons_ver $cons_hash $libs $vers $hashes \
1502 $ext_names $ext_hashes $user_ip_repos $user_ip_vers \
1503 $user_ip_hashes $flavour $xml_ver $xml_hash
1516 if {($globalSettings::vitis_classic == 1 || $globalSettings::vitis_unified == 1)} {
1518 write_hw_platform -fixed -force -file [
file normalize "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"]
1520 if {$options(xsa) == ""} {
1521 set presynth_xsa [
file normalize "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"]
1522 set xsa_opt "-xsa $presynth_xsa"
1525 set xsa_opt "-xsa $options(xsa)"
1527 set xsa_opt "-xsa $globalSettings::repo_path/$options(xsa)"
1531 if {$globalSettings::vitis_classic == 1} {
1533 set xsct_cmd "xsct $globalSettings::tcl_path/launch.tcl C $xsa_opt -vitis_only $globalSettings::project_name"
1534 Msg Info "Running Vitis Classic project creation script with command: $xsct_cmd"
1535 set ret [
catch {
exec -ignorestderr {*}$xsct_cmd >@ stdout} result]
1537 Msg Error "xsct (vitis classic) returned an error state."
1539 }
elseif {$globalSettings::vitis_unified == 1} {
1541 set vivado_cmd "vivado -nojournal -nolog -mode batch -notrace \
1542 -source $globalSettings::tcl_path/launch.tcl \
1543 -tclargs C $xsa_opt -vitis_only $globalSettings::project_name"
1544 Msg Info "Running Vitis Unified project creation script with command: $vivado_cmd"
1545 set ret [
catch {
exec -ignorestderr {*}$vivado_cmd >@ stdout} result]
1547 Msg Error "vivado (vitis unified) returned an error state."
1553 Msg Info "Project $globalSettings::project_name created successfully in [
Relative $globalSettings::repo_path $globalSettings::build_dir]."