29 namespace eval globalSettings {
42 variable LIBERO_MANDATORY_VARIABLES
47 variable HOG_EXTERNAL_PATH
49 variable TARGET_SIMULATOR
51 variable pre_synth_file
52 variable post_synth_file
53 variable pre_impl_file
54 variable post_impl_file
56 variable post_bit_file
57 variable quartus_post_module_file
65 variable synth_top_module
68 variable vitis_classic
69 variable vitis_unified
76 variable quartus_post_module
80 proc InitProject {{vitis_only 0}} {
82 if {[
file exists $globalSettings::build_dir/vitis_classic]} {
83 file delete -force $globalSettings::build_dir/vitis_classic
85 setws $globalSettings::build_dir/vitis_classic
87 if {[
file exists $globalSettings::build_dir/vitis_unified]} {
88 file delete -force $globalSettings::build_dir/vitis_unified
90 file mkdir $globalSettings::build_dir/vitis_unified
95 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..*"}
96 set_msg_config -suppress -regexp -string {".*File '.*.xci' referenced by design '.*' could not be found..*"}
99 set_msg_config -suppress -id {IP_Flow 19-3664}
102 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} }
105 create_project -force [
file tail $globalSettings::DESIGN] $globalSettings::build_dir -part $globalSettings::PART
106 file mkdir "$globalSettings::build_dir/[
file tail $globalSettings::DESIGN].gen/sources_1"
107 if {[
IsVersal $globalSettings::PART]} {
108 Msg Info "This project uses a Versal device."
112 set obj [get_projects [
file tail $globalSettings::DESIGN]]
113 set_property "target_language" "VHDL" $obj
116 set_property "simulator_language" "Mixed" $obj
118 set_property "compxlib.${simulator}_compiled_library_dir" $globalSettings::simlib_path $obj
120 set_property "default_lib" "xil_defaultlib" $obj
122 set_param project.enableVHDL2008 1
123 set_property "enable_vhdl_2008" 1 $obj
125 set_property source_mgmt_mode All [current_project]
127 Msg Debug "Setting PART = $globalSettings::PART"
128 set_property PART $globalSettings::PART [current_project]
133 package require ::quartus::project
135 if {[
string equal $globalSettings::FAMILY "quartus_only"]} {
136 Msg Error "You must specify a device Family for Quartus"
138 file mkdir $globalSettings::build_dir
139 cd $globalSettings::build_dir
140 if {[is_project_open]} {
144 file delete {*}[glob -nocomplain $globalSettings::DESIGN.q*]
146 project_new -family $globalSettings::FAMILY -overwrite -part $globalSettings::PART $globalSettings::DESIGN
147 set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
152 if {[
file exists $globalSettings::build_dir]} {
153 file delete -force $globalSettings::build_dir
155 new_project -location $globalSettings::build_dir \
156 -name [
file tail $globalSettings::DESIGN] \
157 -die $globalSettings::DIE \
158 -package $globalSettings::PACKAGE \
159 -family $globalSettings::FAMILY \
162 if {[
file exists $globalSettings::build_dir]} {
163 file delete -force $globalSettings::build_dir
166 file mkdir $globalSettings::build_dir
167 cd $globalSettings::build_dir
168 prj_project new -name [
file tail $globalSettings::DESIGN] -dev $globalSettings::DEVICE -synthesis $globalSettings::SYNTHESIS_TOOL
172 puts "Creating project for $globalSettings::DESIGN part $globalSettings::PART"
173 puts "Configuring project settings:"
174 puts " - simulator_language: Mixed"
175 puts " - target_language: VHDL"
176 puts " - simulator: QuestaSim"
177 puts "Adding IP directory \"$globalSettings::user_ip_repo\" to the project "
181 proc AddProjectFiles {} {
185 if {[
string equal [get_filesets -quiet sources_1] ""]} {
186 create_fileset -srcset sources_1
188 set sources "sources_1"
200 if {[
string equal [get_filesets -quiet constrs_1] ""]} {
201 create_fileset -constrset constrs_1
205 set constraints [get_filesets constrs_1]
212 if {[
file isdirectory $globalSettings::list_path]} {
213 set list_files [glob -directory $globalSettings::list_path "*"]
215 Msg Error "No list directory found at $globalSettings::list_path"
219 source $globalSettings::tcl_path/utils/cmdline.tcl
223 AddHogFiles {*}[
GetHogFiles -list_files {.src,.sim,.ext} -ext_path $globalSettings::HOG_EXTERNAL_PATH $globalSettings::list_path $globalSettings::repo_path]
229 AddHogFiles {*}[
GetHogFiles -list_files {.con} -ext_path $globalSettings::HOG_EXTERNAL_PATH $globalSettings::list_path $globalSettings::repo_path]
243 proc CreateReportStrategy {obj} {
248 if {[
string equal [get_property -quiet report_strategy $obj] ""]} {
250 Msg Info "No report strategy needed for implementation"
253 set_property set_report_strategy_name 1 $obj
254 set_property report_strategy {Vivado Implementation Default Reports} $obj
255 set_property set_report_strategy_name 0 $obj
257 set reports [get_report_configs -of_objects $obj]
259 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_place_report_utilization_0] ""]} {
260 create_report_config -report_name impl_1_place_report_utilization_0 -report_type report_utilization:1.0 -steps place_design -runs impl_1
262 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_place_report_utilization_0]
268 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_drc_0] ""]} {
269 create_report_config -report_name impl_1_route_report_drc_0 -report_type report_drc:1.0 -steps route_design -runs impl_1
271 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_drc_0]
277 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_power_0] ""]} {
278 create_report_config -report_name impl_1_route_report_power_0 -report_type report_power:1.0 -steps route_design -runs impl_1
280 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_power_0]
286 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_timing_summary] ""]} {
287 create_report_config -report_name impl_1_route_report_timing_summary -report_type report_timing_summary:1.0 -steps route_design -runs impl_1
289 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_timing_summary]
291 Msg Info "Report timing created successfully"
295 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_utilization] ""]} {
296 create_report_config -report_name impl_1_route_report_utilization -report_type report_utilization:1.0 -steps route_design -runs impl_1
298 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_route_report_utilization]
300 Msg Info "Report utilization created successfully"
305 if {[
string equal [get_report_configs -of_objects [get_runs impl_1] impl_1_post_route_phys_opt_report_timing_summary_0] ""]} {
306 create_report_config -report_name impl_1_post_route_phys_opt_report_timing_summary_0 \
307 -report_type report_timing_summary:1.0 \
308 -steps post_route_phys_opt_design -runs impl_1
310 set obj [get_report_configs -of_objects [get_runs impl_1] impl_1_post_route_phys_opt_report_timing_summary_0]
312 set_property -name "options.max_paths" -value "10" -objects $obj
313 set_property -name "options.warn_on_violation" -value "1" -objects $obj
317 Msg Info "Won't create any report strategy, not in Vivado"
327 proc ConfigureSynthesis {} {
331 if {[
string equal [get_runs -quiet synth_1] ""]} {
332 create_run -name synth_1 -part $globalSettings::PART -constrset constrs_1
337 set obj [get_runs synth_1]
338 set_property "part" $globalSettings::PART $obj
342 if {$globalSettings::pre_synth_file ne ""} {
346 if {[get_filesets -quiet utils_1] != ""} {
347 AddFile $globalSettings::pre_synth [get_filesets -quiet utils_1]
349 set_property STEPS.SYNTH_DESIGN.TCL.PRE $globalSettings::pre_synth $obj
353 set_global_assignment -name PRE_FLOW_SCRIPT_FILE quartus_sh:$globalSettings::pre_synth
355 configure_tool -name {SYNTHESIZE} -params SYNPLIFY_TCL_FILE:$globalSettings::pre_synth
357 prj_impl pre_script "syn" $globalSettings::pre_synth
360 Msg Debug "Setting $globalSettings::pre_synth to be run before synthesis"
364 if {$globalSettings::post_synth_file ne ""} {
368 if {[get_filesets -quiet utils_1] != ""} {
369 AddFile $globalSettings::post_synth [get_filesets -quiet utils_1]
371 set_property STEPS.SYNTH_DESIGN.TCL.POST $globalSettings::post_synth $obj
375 set_global_assignment -name POST_MODULE_SCRIPT_FILE quartus_sh:$globalSettings::quartus_post_module
377 prj_impl post_script "syn" $globalSettings::post_synth
379 Msg Debug "Setting $globalSettings::post_synth to be run after synthesis"
386 current_run -synthesis $obj
389 if {[
string equal [get_property -quiet report_strategy $obj] ""]} {
391 Msg Debug "No report strategy needed for synthesis"
394 set_property set_report_strategy_name 1 $obj
395 set_property report_strategy {Vivado Synthesis Default Reports} $obj
396 set_property set_report_strategy_name 0 $obj
398 if {[
string equal [get_report_configs -of_objects [get_runs synth_1] synth_1_synth_report_utilization_0] ""]} {
399 create_report_config -report_name synth_1_synth_report_utilization_0 -report_type report_utilization:1.0 -steps synth_design -runs synth_1
401 set reports [get_report_configs -of_objects [get_runs synth_1] synth_1_synth_report_utilization_0]
411 Msg info "Reporting strategy for synthesis"
420 proc ConfigureImplementation {} {
424 if {[
string equal [get_runs -quiet impl_1] ""]} {
425 create_run -name impl_1 -part $globalSettings::PART -constrset constrs_1 -parent_run synth_1
428 set obj [get_runs impl_1]
429 set_property "part" $globalSettings::PART $obj
431 set_property "steps.[
BinaryStepName $globalSettings::PART].args.readback_file" "0" $obj
432 set_property "steps.[
BinaryStepName $globalSettings::PART].args.verbose" "0" $obj
440 if {$globalSettings::pre_impl_file ne ""} {
444 if {[get_filesets -quiet utils_1] != ""} {
445 AddFile $globalSettings::pre_impl [get_filesets -quiet utils_1]
447 set_property STEPS.INIT_DESIGN.TCL.POST $globalSettings::pre_impl $obj
453 prj_impl pre_script "par" $globalSettings::pre_impl
455 Msg Debug "Setting $globalSettings::pre_impl to be run after implementation"
460 if {$globalSettings::post_impl_file ne ""} {
464 if {[get_filesets -quiet utils_1] != ""} {
465 AddFile $globalSettings::post_impl [get_filesets -quiet utils_1]
467 set_property STEPS.ROUTE_DESIGN.TCL.POST $globalSettings::post_impl $obj
471 set_global_assignment -name POST_MODULE_SCRIPT_FILE quartus_sh:$globalSettings::quartus_post_module
473 prj_impl post_script "par" $globalSettings::post_impl
475 Msg Debug "Setting $globalSettings::post_impl to be run after implementation"
479 if {$globalSettings::pre_bit_file ne ""} {
483 if {[get_filesets -quiet utils_1] != ""} {
484 AddFile $globalSettings::pre_bit [get_filesets -quiet utils_1]
486 set_property STEPS.[
BinaryStepName $globalSettings::PART].TCL.PRE $globalSettings::pre_bit $obj
492 prj_impl pre_script "export" $globalSettings::pre_bit
494 Msg Debug "Setting $globalSettings::pre_bit to be run after bitfile generation"
498 if {$globalSettings::post_bit_file ne ""} {
502 if {[get_filesets -quiet utils_1] != ""} {
503 AddFile $globalSettings::post_bit [get_filesets -quiet utils_1]
505 set_property STEPS.[
BinaryStepName $globalSettings::PART].TCL.POST $globalSettings::post_bit $obj
509 set_global_assignment -name POST_MODULE_SCRIPT_FILE quartus_sh:$globalSettings::quartus_post_module
511 prj_impl post_script "export" $globalSettings::post_bit
513 Msg Debug "Setting $globalSettings::post_bit to be run after bitfile generation"
522 proc ConfigureSimulation {} {
523 set simsets_dict [
GetSimSets "$globalSettings::group_name/$globalSettings::DESIGN" $globalSettings::repo_path]
529 Msg Debug "Setting load_glbl parameter to true for every fileset..."
530 foreach simset [get_filesets -quiet] {
531 if {[get_property FILESET_TYPE $simset] != "SimulationSrcs"} {
535 set_property -name {xsim.elaborate.load_glbl} -value {true} -objects [get_filesets $simset]
538 set sim_dict [
DictGet $simsets_dict $simset]
539 set sim_props [
DictGet $sim_dict "properties"]
541 if {$sim_props != ""} {
542 Msg Info "Setting properties for simulation set: $simset..."
543 dict for {prop_name prop_val} $sim_props {
544 set prop_name [string toupper $prop_name]
545 if {$prop_name == "ACTIVE" && $prop_val == 1} {
546 Msg Info "Setting $simset as active simulation set..."
547 current_fileset -simset [get_filesets $simset]
549 Msg Debug "Setting $prop_name = $prop_val"
550 if {[IsInList [string toupper $prop_name] [VIVADO_PATH_PROPERTIES] 1]} {
551 # Check that the file exists before setting these properties
552 if {[file exists $globalSettings::repo_path/$prop_val]} {
553 set_property -name $prop_name -value $globalSettings::repo_path/$prop_val -objects [get_filesets $simset]
555 Msg Warning "Impossible to set property $prop_name to $prop_val. File is missing"
558 set_property -name $prop_name -value $prop_val -objects [get_filesets $simset]
569 proc ConfigureProperties {} {
571 cd $globalSettings::repo_path
575 if {[
info exists globalSettings::PROPERTIES]} {
576 if {[dict exists $globalSettings::PROPERTIES main]} {
577 Msg Info "Setting project-wide properties..."
578 set proj_props [dict get $globalSettings::PROPERTIES main]
579 dict for {prop_name prop_val} $proj_props {
580 if {[string tolower $prop_name] != "ip_repo_paths"} {
581 if {[string tolower $prop_name] != "part"} {
582 # Part is already set
583 Msg Debug "Setting $prop_name = $prop_val"
584 set_property -name $prop_name -value $prop_val -objects [current_project]
587 set ip_repo_list [regsub -all {\s+} $prop_val " $globalSettings::repo_path/"]
588 set ip_repo_list $globalSettings::repo_path/$ip_repo_list
590 Msg Info "Setting $ip_repo_list as user IP repository..."
592 set_property ip_repo_paths "$ip_repo_list" [current_fileset]
594 set_property ip_repo_paths "$ip_repo_list" [current_project]
601 foreach run [get_runs -quiet] {
602 if {[dict exists $globalSettings::PROPERTIES $run]} {
603 Msg Info "Setting properties for run: $run..."
604 set run_props [dict get $globalSettings::PROPERTIES $run]
606 set stragety_str "STRATEGY strategy Strategy"
607 Msg Debug "Setting Strategy and Flow for run $run (if specified in hog.conf)"
608 foreach s $stragety_str {
609 if {[dict exists $run_props $s]} {
610 set prop [dict get $run_props $s]
611 set_property -name $s -value $prop -objects $run
612 set run_props [dict remove $run_props $s]
613 Msg Warning "A strategy for run $run has been defined inside hog.conf. This prevents Hog to compare the project properties. \
614 Please regenerate your hog.conf file using the dedicated Hog button."
615 Msg Info "Setting $s = $prop"
619 dict for {prop_name prop_val} $run_props {
620 Msg Debug "Setting $prop_name = $prop_val"
621 if {[string trim $prop_val] == ""} {
622 Msg Warning "Property $prop_name has empty value. Skipping..."
625 if {[IsInList [string toupper $prop_name] [VIVADO_PATH_PROPERTIES] 1]} {
626 # Check that the file exists before setting these properties
627 set utility_file $globalSettings::repo_path/$prop_val
628 if {[file exists $utility_file]} {
629 lassign [GetHogFiles -ext_path $globalSettings::HOG_EXTERNAL_PATH $globalSettings::list_path $globalSettings::repo_path] lib prop dummy
632 lappend hog_files $ff
635 if {[lsearch $hog_files $utility_file] < 0} {
636 Msg CriticalWarning "The file: $utility_file is set as a property in hog.conf, \
637 but is not added to the project in any list file. Hog cannot track it."
639 #Add file tu utils_1 to avoid warning
640 AddFile $globalSettings::repo_path/$prop_val [get_filesets -quiet utils_1]
642 set_property -name $prop_name -value $utility_file -objects $run
644 Msg Warning "Impossible to set property $prop_name to $prop_val. File is missing"
647 set_property -name $prop_name -value $prop_val -objects $run
658 if {[
info exists globalSettings::PROPERTIES]} {
660 if {[dict exists $globalSettings::PROPERTIES main]} {
661 Msg Info "Setting device properties..."
662 set dev_props [dict get $globalSettings::PROPERTIES main]
663 dict for {prop_name prop_val} $dev_props {
664 if {!([string toupper $prop_name] in $globalSettings::LIBERO_MANDATORY_VARIABLES)} {
665 Msg Debug "Setting $prop_name = $prop_val"
666 set_device -[string tolower $prop_name] $prop_val
671 if {[dict exists $globalSettings::PROPERTIES project]} {
672 Msg Info "Setting project-wide properties..."
673 set dev_props [dict get $globalSettings::PROPERTIES project]
674 dict for {prop_name prop_val} $dev_props {
675 Msg Debug "Setting $prop_name = $prop_val"
676 project_settings -[string tolower $prop_name] $prop_val
680 if {[dict exists $globalSettings::PROPERTIES synth]} {
681 Msg Info "Setting Synthesis properties..."
682 set synth_props [dict get $globalSettings::PROPERTIES synth]
683 dict for {prop_name prop_val} $synth_props {
684 Msg Debug "Setting $prop_name = $prop_val"
685 configure_tool -name {SYNTHESIZE} -params "[string toupper $prop_name]:$prop_val"
689 if {[dict exists $globalSettings::PROPERTIES impl]} {
690 Msg Info "Setting Implementation properties..."
691 set impl_props [dict get $globalSettings::PROPERTIES impl]
692 dict for {prop_name prop_val} $impl_props {
693 Msg Debug "Setting $prop_name = $prop_val"
694 configure_tool -name {PLACEROUTE} -params "[string toupper $prop_name]:$prop_val"
699 if {[dict exists $globalSettings::PROPERTIES bitstream]} {
700 Msg Info "Setting Bitstream properties..."
701 set impl_props [dict get $globalSettings::PROPERTIES impl]
702 dict for {prop_name prop_val} $impl_props {
703 Msg Debug "Setting $prop_name = $prop_val"
704 configure_tool -name {GENERATEPROGRAMMINGFILE} -params "[string toupper $prop_name]:$prop_val"
708 configure_tool -name {VERIFYTIMING} -params {FORMAT:TEXT}
711 if {[
info exists globalSettings::PROPERTIES]} {
713 if {[dict exists $globalSettings::PROPERTIES main]} {
714 Msg Info "Setting project-wide properties..."
715 set dev_props [dict get $globalSettings::PROPERTIES main]
716 dict for {prop_name prop_val} $dev_props {
717 # Device is already set
718 if {[string toupper $prop_name] != "DEVICE"} {
719 Msg Debug "Setting $prop_name = $prop_val"
720 prj_project option $prop_name $prop_val
725 if {[dict exists $globalSettings::PROPERTIES impl]} {
726 Msg Info "Setting Implementation properties..."
727 set dev_props [dict get $globalSettings::PROPERTIES impl]
728 dict for {prop_name prop_val} $dev_props {
729 # Device is already set
730 Msg Debug "Setting $prop_name = $prop_val"
731 prj_impl option $prop_name $prop_val
736 Msg info "Configuring Properties"
742 proc ConfigurePlatforms {{xsa ""}} {
743 dict for {key value} [dict filter $globalSettings::PROPERTIES key {platform:*}] {
744 set value_lower [dict create]
745 dict for {vkey vvalue} $value {
746 dict set value_lower [string tolower $vkey] $vvalue
748 dict set platforms $key $value_lower
754 dict for {key value} $platforms2 {
755 Msg Info "Key: $key, Value: $value"
758 if {[dict size $platforms] == 0} {
759 Msg Info "No platforms found in the configuration file"
763 dict for {platform_key platform_config} $platforms {
764 Msg Info "Found platform with key: $platform_key with configuration: $platform_config"
765 if {[regexp {^platform:(.+)$} $platform_key -> platform_name]} {
766 set platform_name [string trim $platform_name]
767 Msg Info "Configuring platform: $platform_name"
768 CreatePlatform $platform_name $platform_config $xsa
770 Msg Warning "Invalid platform key format: $platform_key. Expected format: platform:<name>"
775 proc CreatePlatform {platform_name platform_conf {xsa ""}} {
777 set platform_create_options {
778 "desc" "hw" "out" "prebuilt" "proc" "arch"
779 "samples" "os" "xpfm" "no-boot-bsp"
782 Msg Info "Creating platform configuration..."
783 append platform_options " -name $platform_name"
786 if {[
catch {
set ws_platforms [platform list -dict]}]} {
set ws_platforms ""}
787 if {[lsearch -exact $ws_platforms $platform_name] != -1} {
788 Msg Info "Platform $platform_name already exists, removing it..."
789 platform remove $platform_name
792 dict for {p v} $platform_conf {
793 if {[IsInList [string toupper $p] [VITIS_PATH_PROPERTIES] 1]} {
795 if {[IsRelativePath $v] == 1} {
796 set v "$globalSettings::repo_path/$v"
799 if {[file exists $v]} {
804 Msg Warning "Impossible to set property $p to $v. File is missing"
809 set p_lower [string tolower $p]
810 if {[IsInList $p_lower $platform_create_options]} {
811 append platform_options " -$p_lower $v"
813 if {$p_lower ne "bif"} {
814 Msg Warning "Attempting to use unknown platform option: $p_lower"
815 append platform_options " -$p_lower $v"
823 set platform_options "$platform_options -hw $xsa"
824 }
elseif {![dict exists $platform_conf hw]} {
825 set xsa "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"
826 set platform_options "$platform_options -hw $xsa"
828 set platform_options "$platform_options"
833 Msg Info "Opening hardware design to check if proc to cell mapping needs to be extracted for soft processors..."
835 hsi::open_hw_design $xsa
836 set proc_cells [hsi::get_cells -filter { IP_TYPE == "PROCESSOR" }]
837 set proc_map_file [open "$globalSettings::build_dir/vitis_classic/$platform_name.PROC_MAP" "w"]
839 foreach proc $proc_cells {
841 Msg Debug "Processor found in xsa: $proc"
842 if {[regexp -nocase {microblaze|risc} $proc]} {
843 Msg Info "Extracting processor cells for soft processor: $proc"
844 set proc_hier_name [hsi::get_property HIER_NAME $proc]
845 set proc_address_tag [hsi::get_property ADDRESS_TAG $proc]
847 if {$proc_address_tag eq ""} {
848 Msg Warning "Processor $proc ($proc_hier_name) does not have an ADDRESS_TAG property set. \
849 This may cause issues when configuring the platform."
851 set proc_map_entry "$proc_hier_name $proc_address_tag"
852 puts $proc_map_file "$proc_map_entry\n"
857 hsi::close_hw_design [hsi::current_hw_design]
862 Msg Info "Creating platform \[$platform_name\] with options: \{$platform_options\}"
864 set plat_create "platform create $platform_options"
866 platform active $platform_name
870 set python_script "$globalSettings::repo_path/Hog/Other/Python/VitisUnified/PlatformCommands.py"
871 Msg Info "Running Vitis Unified platform creation script..."
872 set platform_options_str "{ $platform_options }"
873 set error_msg "Failed to create platform $platform_name"
875 [list $platform_options_str "$globalSettings::build_dir/vitis_unified"] \
883 proc ConfigureApps {} {
884 set apps [dict filter $globalSettings::PROPERTIES key {app:*}]
886 if {[dict size $apps] == 0} {
887 Msg Info "No apps found in the configuration file"
891 dict for {app_key app_config} $apps {
892 Msg Info "Found app with key: $app_key with configuration: $app_config"
893 if {[regexp {^app:(.+)$} $app_key -> app_name]} {
894 set app_name [string trim $app_name]
895 Msg Info "Configuring app: $app_name"
896 if {[IsVitisClassic]} {
897 ConfigureApp $app_name $app_config
898 } elseif {[IsVitisUnified]} {
899 set python_script "$globalSettings::repo_path/Hog/Other/Python/VitisUnified/AppCommands.py"
900 Msg Info "Running Vitis Unified app configuration script..."
901 # Build app config string from app_config dict
902 set app_config_str "{"
903 dict for {p v} $app_config {
904 append app_config_str " -[string toupper $p] \{$v\}"
906 append app_config_str " }"
907 set error_msg "Failed to configure app $app_name"
908 if {![ExecuteVitisUnifiedCommand $python_script "configure_app" \
909 [list $app_name $app_config_str "$globalSettings::build_dir/vitis_unified"] \
915 Msg Warning "Invalid app key format: $app_key. Expected format: app:<name>"
920 proc ConfigureApp {app_name app_conf} {
923 "platform" "domain" "sysproj" "hw"
924 "proc" "template" "os" "lang" "arch" "name"
928 "assembler-flags" "build-config" "compiler-misc" "compiler-optimization"
929 "define-compiler-symbols" "include-path" "libraries" "library-search-path"
930 "linker-misc" "linker-script" "undef-compiler-symbols"
933 Msg Info "Configuring app..."
934 append app_options " -name $app_name"
937 if {[
catch {
set sys_projs [sysproj list -dict]}]} {
set sys_projs ""}
938 if {[dict exists $app_name sysproj]} {
939 set sys_proj_name [dict get $app_name sysproj]
940 if {[lsearch -exact $sys_projs "Name $sys_proj_name"] != -1} {
941 Msg Info "Removing $sys_proj_name..."
942 sysproj remove $sys_proj_name
945 set sys_proj_name "$app_name\_system"
946 if {[lsearch -exact $sys_projs "Name $sys_proj_name"] != -1} {
947 Msg Info "Removing $sys_proj_name..."
948 sysproj remove $sys_proj_name
953 if {[
catch {
set ws_apps [app list -dict]}]} {
set ws_apps ""}
954 if {[lsearch -exact $ws_apps $app_name] != -1} {
955 Msg Info "app $app_name already exists, removing it..."
959 set app_create_options [dict create]
960 set app_conf_options [dict create]
963 dict for {p v} $app_conf {
964 set p_lower [string tolower $p]
966 if {[IsInList [string toupper $p] [VITIS_PATH_PROPERTIES] 1]} {
967 if {[IsRelativePath $v] == 1} {
968 set v "$globalSettings::repo_path/$v"
971 if {![file exists $v]} {
972 Msg Warning "Impossible to set property $p to $v. File is missing"
977 if {[IsInList $p_lower $create_options]} {
978 Msg Info "$p_lower is in create options"
979 dict append app_create_options $p_lower $v
980 } elseif {[IsInList $p_lower $conf_options]} {
981 Msg Info "$p_lower is in conf options"
982 dict append app_conf_options $p_lower $v
984 Msg Warning "Unknown app option: $p_lower"
989 dict for {p v} $app_create_options {
990 if {[string equal $p "platform"]} {
991 Msg Info "Setting App $app_name platform to $v"
994 append app_options " -$p $v"
997 if {![dict exists $app_name template]} {
1000 if {[dict exists $app_create_options "lang"]} {
1001 set lang [dict get $app_create_options "lang"]
1002 if {[
string equal -nocase $lang "C++"] || [
string equal -nocase $lang "cpp"]} {
1003 append app_options " -template \{Empty Application (C++)\}"
1005 append app_options " -template \{Empty Application(C)\}"
1009 append app_options " -template \{Empty Application(C)\}"
1013 append app_options " -template \{Empty Application\}"
1017 Msg Info "Creating application \[$app_name\] with options: \{$app_options\}"
1018 set app_create "app create $app_options"
1020 app config -name $app_name -set build-config Release
1023 dict for {p v} $app_conf_options {
1024 Msg Info "Configuring app option $p to $v"
1025 app config -name $app_name -set $p $v
1030 proc AddAppFiles {} {
1031 AddHogFiles {*}[
GetHogFiles -list_files {.src,.header} -ext_path $globalSettings::HOG_EXTERNAL_PATH $globalSettings::list_path $globalSettings::repo_path]
1044 proc ConfigureHlsComponents {} {
1045 set hls_components [dict filter $globalSettings::PROPERTIES key {hls:*}]
1047 if {[dict size $hls_components] == 0} {
1048 Msg Info "No HLS components found in the configuration file"
1052 set python_script "$globalSettings::repo_path/Hog/Other/Python/VitisUnified/HlsCommands.py"
1053 set ws_dir [
file normalize "$globalSettings::build_dir/vitis_unified"]
1055 dict for {hls_key hls_config} $hls_components {
1056 if {[regexp {^hls:(.+)$} $hls_key -> component_name]} {
1057 set component_name [string trim $component_name]
1058 Msg Info "Configuring HLS component: $component_name"
1060 # Get HLS_CONFIG path from hog.conf (mandatory)
1062 if {[dict exists $hls_config hls_config]} {
1063 set hls_cfg_rel [dict get $hls_config hls_config]
1064 } elseif {[dict exists $hls_config HLS_CONFIG]} {
1065 set hls_cfg_rel [dict get $hls_config HLS_CONFIG]
1067 if {$hls_cfg_rel eq ""} {
1068 Msg Error "HLS component '$component_name' missing HLS_CONFIG in hog.conf \[hls:$component_name\] section"
1072 set hls_cfg_file [file normalize "$globalSettings::repo_path/$hls_cfg_rel"]
1073 if {![file exists $hls_cfg_file]} {
1074 Msg Error "HLS config file not found: $hls_cfg_file (from HLS_CONFIG=$hls_cfg_rel)"
1078 Msg Info " HLS config: $hls_cfg_file"
1080 # Validate the config file
1081 set error_msg "Failed to validate HLS config for $component_name"
1082 if {![ExecuteVitisUnifiedCommand $python_script "validate" \
1083 [list $hls_cfg_file] \
1085 Msg Error $error_msg
1089 # Create Vitis workspace with HLS component for GUI compatibility
1090 set hls_work_dir [file normalize "$ws_dir/hls_$component_name"]
1091 Msg Info "Creating Vitis HLS workspace component '$component_name' in $ws_dir ..."
1092 if {![ExecuteVitisUnifiedCommand $python_script "create_workspace" \
1093 [list $ws_dir $component_name $hls_cfg_file $hls_work_dir] \
1094 "Failed to create HLS workspace for $component_name"]} {
1095 Msg Warning "Could not create Vitis workspace for HLS component '$component_name'"
1098 Msg Info "HLS component '$component_name' configured successfully"
1100 Msg Warning "Invalid HLS key format: $hls_key. Expected format: hls:<name>"
1109 current_run -implementation [get_runs impl_1]
1116 Msg Info "Running report_ip_status, before upgrading and handling IPs..."
1119 if {$globalSettings::HOG_IP_PATH != ""} {
1120 set ip_repo_path $globalSettings::HOG_IP_PATH
1121 Msg Info "HOG_IP_PATH is set, will pull/push synthesised IPs from/to $ip_repo_path."
1123 HandleIP pull [get_property IP_FILE $ip] $ip_repo_path $globalSettings::repo_path [get_property IP_OUTPUT_DIR $ip]
1126 Msg Info "HOG_IP_PATH not set, will not push/pull synthesised IPs."
1130 proc SetGlobalVar {var {default_value HOG_NONE}} {
1132 if {[
info exists ::$var]} {
1133 Msg Debug "Setting $var to [subst $[subst ::$var]]"
1135 set globalSettings::$var [subst $[subst ::$var]]
1136 }
elseif {$default_value == "HOG_NONE"} {
1137 Msg Error "Mandatory variable $var was not defined. Please define it in hog.conf or in project tcl script."
1139 Msg Info "Setting $var to default value: \"$default_value\""
1141 set globalSettings::$var $default_value
1147 proc CreateProject {args} {
1152 if {[
catch {
package require cmdline} ERROR]} {
1153 puts "ERROR: If you are running this script on tclsh, you can fix this by installing 'tcllib'"
1157 {simlib_path.arg "" "Path of simulation libs"}
1158 {verbose "If set, launch the script in verbose mode."}
1159 {xsa.arg "" "xsa for creating platforms without a defined hw."}
1160 {vivado_only "If set, and project is vivado-vitis, vitis project will not be created."}
1161 {vitis_only "If set, and project is vivado-vitis, only vitis project will be created."}
1164 set usage "Create Vivado/Vitis/ISE/Quartus/Libero/Diamond project.\nUsage: CreateProject \[OPTIONS\] <project> <repository path>\n Options:"
1166 if {[
catch {
array set options [
cmdline::getoptions args $parameters $usage]}] || [
llength $args] < 2 || [
lindex $args 0] eq ""} {
1171 set globalSettings::DESIGN [
lindex $args 0]
1172 if {[
file exists [
lindex $args 1]]} {
1173 set globalSettings::repo_path [
file normalize [
lindex $args 1]]
1175 Msg Error "The second argument, [
lindex $args 1], should be the repository path."
1177 set globalSettings::tcl_path $globalSettings::repo_path/Hog/Tcl
1180 if {$options(verbose) == 1} {
1181 variable ::DEBUG_MODE 1
1185 if {$options(simlib_path) != ""} {
1187 set globalSettings::simlib_path "$options(simlib_path)"
1189 set globalSettings::simlib_path "${globalSettings::repo_path}/$options(simlib_path)"
1191 Msg Info "Simulation library path set to $options(simlib_path)"
1193 set globalSettings::simlib_path "${globalSettings::repo_path}/SimulationLib"
1194 Msg Info "Simulation library path set to default ${globalSettings::repo_path}/SimulationLib"
1200 set build_dir_name "Projects"
1201 set globalSettings::group_name [
file dirname ${globalSettings::DESIGN}]
1202 set globalSettings::project_name ${globalSettings::DESIGN}
1203 set globalSettings::pre_synth_file "pre-synthesis.tcl"
1204 set globalSettings::post_synth_file "post-synthesis.tcl"
1205 set globalSettings::pre_impl_file "pre-implementation.tcl"
1206 set globalSettings::post_impl_file "post-implementation.tcl"
1207 set globalSettings::pre_bit_file "pre-bitstream.tcl"
1208 set globalSettings::post_bit_file "post-bitstream.tcl"
1209 set globalSettings::quartus_post_module_file "quartus-post-module.tcl"
1210 set globalSettings::top_path "${globalSettings::repo_path}/Top/${globalSettings::DESIGN}"
1211 set globalSettings::list_path "${globalSettings::top_path}/list"
1212 set globalSettings::build_dir "${globalSettings::repo_path}/${build_dir_name}/${globalSettings::DESIGN}"
1213 set globalSettings::DESIGN [
file tail ${globalSettings::DESIGN}]
1214 set globalSettings::top_name [
file tail ${globalSettings::DESIGN}]
1215 set globalSettings::top_name [
file rootname ${globalSettings::top_name}]
1216 set globalSettings::synth_top_module "top_${globalSettings::top_name}"
1217 set globalSettings::user_ip_repo ""
1219 set globalSettings::pre_synth [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::pre_synth_file}"]
1220 set globalSettings::post_synth [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::post_synth_file}"]
1221 set globalSettings::pre_impl [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::pre_impl_file}"]
1222 set globalSettings::post_impl [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::post_impl_file}"]
1223 set globalSettings::pre_bit [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::pre_bit_file}"]
1224 set globalSettings::post_bit [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::post_bit_file}"]
1225 set globalSettings::quartus_post_module [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::quartus_post_module_file}"]
1226 set globalSettings::LIBERO_MANDATORY_VARIABLES {"FAMILY" "PACKAGE" "DIE" }
1228 set proj_dir [
file normalize "${globalSettings::repo_path}/Top/${globalSettings::project_name}"]
1229 Msg Debug "Calling GetConfFiles with proj_dir=$proj_dir (project_name=${globalSettings::project_name})"
1230 lassign [
GetConfFiles $proj_dir] conf_file sim_file pre_file post_file pre_rtl_file
1233 if {[
file exists $conf_file]} {
1234 Msg Info "Parsing configuration file $conf_file..."
1241 if {$conf_version != "0.0.0"} {
1242 set globalSettings::a_v [
split $actual_version "."]
1243 set globalSettings::c_v [
split $conf_version "."]
1245 if {[
llength $globalSettings::a_v] < 2} {
1246 Msg Error "Couldn't parse IDE version: $actual_version."
1247 }
elseif {[
llength $globalSettings::a_v] == 2} {
1248 lappend globalSettings::a_v 0
1250 if {[
llength $globalSettings::c_v] < 2} {
1251 Msg Error "Wrong version format in hog.conf: $conf_version."
1252 }
elseif {[
llength $globalSettings::c_v] == 2} {
1253 lappend globalSettings::c_v 0
1258 Msg Info "Project version and $ide version match: $conf_version."
1259 }
elseif {$comp == 1} {
1260 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\
1261 If you want update this project to version $actual_version, please update the configuration file."
1264 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."
1267 Msg CriticalWarning "No version found in the first line of $conf_file. \
1268 It is HIGHLY recommended to replace the first line of $conf_file with: \#$ide $actual_version"
1271 if {$globalSettings::vitis_classic == 1} {
1273 Msg Error "Vitis Classic flow is not supported for versions < 2020.2. Please use Vitis 2020.2 or newer."}
1275 if {$globalSettings::vitis_unified == 1} {
1277 Msg Error "Vitis Unified flow is not supported for versions < 2019.2. Please use Vitis 2019.2 or newer."}
1280 if {[dict exists $globalSettings::PROPERTIES main]} {
1281 set main [dict get $globalSettings::PROPERTIES main]
1282 dict for {p v} $main {
1283 # notice the dollar in front of p: creates new variables and fill them with the value
1284 Msg Info "Main property $p set to $v"
1289 Msg Error "No main section found in $conf_file, make sure it has a section called \[main\] containing the mandatory properties."
1292 Msg Error "$conf_file was not found in your project directory, please create one."
1318 if {[
info exists env(HOG_EXTERNAL_PATH)]} {
1319 set globalSettings::HOG_EXTERNAL_PATH $env(HOG_EXTERNAL_PATH)
1321 set globalSettings::HOG_EXTERNAL_PATH ""
1324 set user_hog_file "${globalSettings::repo_path}/Top/hog.tcl"
1325 if {[
file exists $user_hog_file]} {
1326 Msg Info "Sourcing user hog.tcl file..."
1327 source $user_hog_file
1330 if {[
file exists $pre_file]} {
1331 Msg Info "Found pre-creation Tcl script $pre_file, executing it..."
1335 if {[
info exists env(HOG_IP_PATH)]} {
1336 set globalSettings::HOG_IP_PATH $env(HOG_IP_PATH)
1338 set globalSettings::HOG_IP_PATH ""
1345 set has_hls [
expr {[dict size [dict filter $globalSettings::PROPERTIES key {hls:*}]] > 0}]
1346 set has_platforms [
expr {[dict size [dict filter $globalSettings::PROPERTIES key {platform:*}]] > 0}]
1347 set has_apps [
expr {[dict size [dict filter $globalSettings::PROPERTIES key {app:*}]] > 0}]
1350 Msg Info "Found HLS component(s) in configuration, configuring HLS..."
1354 if {!$has_platforms && !$has_apps} {
1355 Msg Info "vitis unified HLS-only project, skipping Vivado project setup."
1359 if {$has_platforms || $has_apps} {
1360 set xsa_path $options(xsa)
1362 if {$xsa_path == ""} {
1363 if {[
string match "vivado_*" [
string tolower $ide]]} {
1365 set xpr_file [
file normalize "$globalSettings::build_dir/[
file tail $globalSettings::DESIGN].xpr"]
1366 if {[
file exists $xpr_file]} {
1367 Msg Info "Opening existing Vivado project to generate pre-synth XSA..."
1368 open_project $xpr_file
1369 set xsa_path [
file normalize "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"]
1370 write_hw_platform -fixed -force -file $xsa_path
1371 Msg Info "Pre-synth XSA generated: $xsa_path"
1375 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."
1380 Msg Error "This is a $ide only project with platform/app sections, an XSA file must be provided via the -xsa option."
1385 Msg Info "Configuring platforms with XSA: $xsa_path"
1395 if {([
string tolower $ide] eq "vitis_classic" || [
string tolower $ide] eq "vitis_unified") && $options(vitis_only) == 1} {
1396 if {$options(xsa) == ""} {
1397 Msg Error "This is a $ide only project, an XSA file must be provided via -xsa option."
1415 set fileName_old [
file normalize "./hogTmp/.hogQsys.md5"]
1416 set fileDir [
file normalize "${globalSettings::build_dir}/.hog/"]
1418 set fileName_new [
file normalize "$fileDir/.hogQsys.md5"]
1419 if {[
file exists $fileName_new]} {
1420 file delete $fileName_new
1422 if {[
file exists $fileName_old]} {
1423 file rename -force $fileName_old $fileName_new
1424 file delete -force -- "./hogTmp"
1428 if {[
file exists $post_file]} {
1429 Msg Info "Found post-creation Tcl script $post_file, executing it..."
1433 build_design_hierarchy
1440 -ext_path "$globalSettings::HOG_EXTERNAL_PATH" \
1441 -list_files ".src,.ext" \
1442 "$globalSettings::repo_path/Top/$globalSettings::project_name/list/" \
1443 $globalSettings::repo_path] \
1444 listLibraries listProperties listSrcSets
1447 -ext_path "$globalSettings::HOG_EXTERNAL_PATH" \
1448 -list_files ".con" \
1449 "$globalSettings::repo_path/Top/$globalSettings::project_name/list/" \
1450 $globalSettings::repo_path] \
1451 listConstraints listConProperties listConSets
1454 -ext_path "$globalSettings::HOG_EXTERNAL_PATH" \
1455 -list_files ".sim" \
1456 "$globalSettings::repo_path/Top/$globalSettings::project_name/list/" \
1457 $globalSettings::repo_path] \
1458 listSimLibraries listSimProperties listSimSets
1461 cd $globalSettings::build_dir
1467 cd $globalSettings::repo_path
1471 [
file normalize $globalSettings::repo_path/Top/$globalSettings::project_name] \
1472 $globalSettings::repo_path \
1473 $globalSettings::HOG_EXTERNAL_PATH
1474 ] commit version hog_hash hog_ver top_hash top_ver libs hashes vers cons_ver cons_hash ext_names ext_hashes \
1475 xml_hash xml_ver user_ip_repos user_ip_hashes user_ip_vers
1480 set commit $this_commit
1483 if {$xml_hash != ""} {
1492 $globalSettings::repo_path \
1493 $globalSettings::project_name \
1494 $date $timee $commit $version \
1495 $top_hash $top_ver $hog_hash $hog_ver \
1496 $cons_ver $cons_hash $libs $vers $hashes \
1497 $ext_names $ext_hashes $user_ip_repos $user_ip_vers \
1498 $user_ip_hashes $flavour $xml_ver $xml_hash
1511 if {($globalSettings::vitis_classic == 1 || $globalSettings::vitis_unified == 1)} {
1513 write_hw_platform -fixed -force -file [
file normalize "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"]
1515 if {$options(xsa) == ""} {
1516 set presynth_xsa [
file normalize "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"]
1517 set xsa_opt "-xsa $presynth_xsa"
1520 set xsa_opt "-xsa $options(xsa)"
1522 set xsa_opt "-xsa $globalSettings::repo_path/$options(xsa)"
1526 if {$globalSettings::vitis_classic == 1} {
1528 set xsct_cmd "xsct $globalSettings::tcl_path/launch.tcl C $xsa_opt -vitis_only $globalSettings::project_name"
1529 Msg Info "Running Vitis Classic project creation script with command: $xsct_cmd"
1530 set ret [
catch {
exec -ignorestderr {*}$xsct_cmd >@ stdout} result]
1532 Msg Error "xsct (vitis classic) returned an error state."
1534 }
elseif {$globalSettings::vitis_unified == 1} {
1536 set vivado_cmd "vivado -nojournal -nolog -mode batch -notrace \
1537 -source $globalSettings::tcl_path/launch.tcl \
1538 -tclargs C $xsa_opt -vitis_only $globalSettings::project_name"
1539 Msg Info "Running Vitis Unified project creation script with command: $vivado_cmd"
1540 set ret [
catch {
exec -ignorestderr {*}$vivado_cmd >@ stdout} result]
1542 Msg Error "vivado (vitis unified) returned an error state."
1548 Msg Info "Project $globalSettings::project_name created successfully in [
Relative $globalSettings::repo_path $globalSettings::build_dir]."