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_path [
file normalize "$globalSettings::build_dir/vitis_classic/$platform_name.PROC_MAP"]
839 set proc_map_file [open $proc_map_path "w"]
841 foreach proc $proc_cells {
843 Msg Debug "Processor found in xsa: $proc"
844 if {[regexp -nocase {microblaze|risc} $proc]} {
845 Msg Info "Extracting processor cells for soft processor: $proc"
846 set proc_hier_name [hsi::get_property HIER_NAME $proc]
847 set proc_address_tag [hsi::get_property ADDRESS_TAG $proc]
851 set proc_updatemem_path $proc_hier_name
852 if {$proc_address_tag ne ""} {
853 if {[
string match "*:*" $proc_address_tag]} {
854 set proc_updatemem_path [
lindex [
split $proc_address_tag ":"] end]
856 set proc_updatemem_path $proc_address_tag
859 Msg Warning "Processor $proc ($proc_hier_name) does not have an ADDRESS_TAG property set. Using HIER_NAME for updatemem."
861 if {$proc_updatemem_path eq ""} {
862 set proc_updatemem_path $proc
866 puts $proc_map_file "$proc $proc_updatemem_path"
867 if {$proc_hier_name ne "" && $proc_hier_name ne $proc} {
868 puts $proc_map_file "$proc_hier_name $proc_updatemem_path"
873 hsi::close_hw_design [hsi::current_hw_design]
875 Msg Info "Wrote soft-processor map to $proc_map_path"
879 Msg Info "Creating platform \[$platform_name\] with options: \{$platform_options\}"
881 set plat_create "platform create $platform_options"
883 platform active $platform_name
887 set python_script "$globalSettings::repo_path/Hog/Other/Python/VitisUnified/PlatformCommands.py"
888 Msg Info "Running Vitis Unified platform creation script..."
889 set platform_options_str "{ $platform_options }"
890 set error_msg "Failed to create platform $platform_name"
892 [list $platform_options_str "$globalSettings::build_dir/vitis_unified"] \
900 proc ConfigureApps {} {
901 set apps [dict filter $globalSettings::PROPERTIES key {app:*}]
903 if {[dict size $apps] == 0} {
904 Msg Info "No apps found in the configuration file"
908 dict for {app_key app_config} $apps {
909 Msg Info "Found app with key: $app_key with configuration: $app_config"
910 if {[regexp {^app:(.+)$} $app_key -> app_name]} {
911 set app_name [string trim $app_name]
912 Msg Info "Configuring app: $app_name"
913 if {[IsVitisClassic]} {
914 ConfigureApp $app_name $app_config
915 } elseif {[IsVitisUnified]} {
916 set python_script "$globalSettings::repo_path/Hog/Other/Python/VitisUnified/AppCommands.py"
917 Msg Info "Running Vitis Unified app configuration script..."
918 # Build app config string from app_config dict
919 set app_config_str "{"
920 dict for {p v} $app_config {
921 append app_config_str " -[string toupper $p] \{$v\}"
923 append app_config_str " }"
924 set error_msg "Failed to configure app $app_name"
925 if {![ExecuteVitisUnifiedCommand $python_script "configure_app" \
926 [list $app_name $app_config_str "$globalSettings::build_dir/vitis_unified"] \
932 Msg Warning "Invalid app key format: $app_key. Expected format: app:<name>"
937 proc ConfigureApp {app_name app_conf} {
940 "platform" "domain" "sysproj" "hw"
941 "proc" "template" "os" "lang" "arch" "name"
945 "assembler-flags" "build-config" "compiler-misc" "compiler-optimization"
946 "define-compiler-symbols" "include-path" "libraries" "library-search-path"
947 "linker-misc" "linker-script" "undef-compiler-symbols"
950 Msg Info "Configuring app..."
951 append app_options " -name $app_name"
954 if {[
catch {
set sys_projs [sysproj list -dict]}]} {
set sys_projs ""}
955 if {[dict exists $app_name sysproj]} {
956 set sys_proj_name [dict get $app_name sysproj]
957 if {[lsearch -exact $sys_projs "Name $sys_proj_name"] != -1} {
958 Msg Info "Removing $sys_proj_name..."
959 sysproj remove $sys_proj_name
962 set sys_proj_name "$app_name\_system"
963 if {[lsearch -exact $sys_projs "Name $sys_proj_name"] != -1} {
964 Msg Info "Removing $sys_proj_name..."
965 sysproj remove $sys_proj_name
970 if {[
catch {
set ws_apps [app list -dict]}]} {
set ws_apps ""}
971 if {[lsearch -exact $ws_apps $app_name] != -1} {
972 Msg Info "app $app_name already exists, removing it..."
976 set app_create_options [dict create]
977 set app_conf_options [dict create]
980 dict for {p v} $app_conf {
981 set p_lower [string tolower $p]
983 if {[IsInList [string toupper $p] [VITIS_PATH_PROPERTIES] 1]} {
984 if {[IsRelativePath $v] == 1} {
985 set v "$globalSettings::repo_path/$v"
988 if {![file exists $v]} {
989 Msg Warning "Impossible to set property $p to $v. File is missing"
994 if {[IsInList $p_lower $create_options]} {
995 Msg Info "$p_lower is in create options"
996 dict append app_create_options $p_lower $v
997 } elseif {[IsInList $p_lower $conf_options]} {
998 Msg Info "$p_lower is in conf options"
999 dict append app_conf_options $p_lower $v
1001 Msg Warning "Unknown app option: $p_lower"
1006 dict for {p v} $app_create_options {
1007 if {[string equal $p "platform"]} {
1008 Msg Info "Setting App $app_name platform to $v"
1011 append app_options " -$p $v"
1014 if {![dict exists $app_name template]} {
1017 if {[dict exists $app_create_options "lang"]} {
1018 set lang [dict get $app_create_options "lang"]
1019 if {[
string equal -nocase $lang "C++"] || [
string equal -nocase $lang "cpp"]} {
1020 append app_options " -template \{Empty Application (C++)\}"
1022 append app_options " -template \{Empty Application(C)\}"
1026 append app_options " -template \{Empty Application(C)\}"
1030 append app_options " -template \{Empty Application\}"
1034 Msg Info "Creating application \[$app_name\] with options: \{$app_options\}"
1035 set app_create "app create $app_options"
1037 app config -name $app_name -set build-config Release
1040 dict for {p v} $app_conf_options {
1041 Msg Info "Configuring app option $p to $v"
1042 app config -name $app_name -set $p $v
1047 proc AddAppFiles {} {
1048 AddHogFiles {*}[
GetHogFiles -list_files {.src,.header} -ext_path $globalSettings::HOG_EXTERNAL_PATH $globalSettings::list_path $globalSettings::repo_path]
1061 proc ConfigureHlsComponents {} {
1062 set hls_components [dict filter $globalSettings::PROPERTIES key {hls:*}]
1064 if {[dict size $hls_components] == 0} {
1065 Msg Info "No HLS components found in the configuration file"
1069 set python_script "$globalSettings::repo_path/Hog/Other/Python/VitisUnified/HlsCommands.py"
1070 set ws_dir [
file normalize "$globalSettings::build_dir/vitis_unified"]
1072 dict for {hls_key hls_config} $hls_components {
1073 if {[regexp {^hls:(.+)$} $hls_key -> component_name]} {
1074 set component_name [string trim $component_name]
1075 Msg Info "Configuring HLS component: $component_name"
1077 # Get HLS_CONFIG path from hog.conf (mandatory)
1079 if {[dict exists $hls_config hls_config]} {
1080 set hls_cfg_rel [dict get $hls_config hls_config]
1081 } elseif {[dict exists $hls_config HLS_CONFIG]} {
1082 set hls_cfg_rel [dict get $hls_config HLS_CONFIG]
1084 if {$hls_cfg_rel eq ""} {
1085 Msg Error "HLS component '$component_name' missing HLS_CONFIG in hog.conf \[hls:$component_name\] section"
1089 set hls_cfg_file [file normalize "$globalSettings::repo_path/$hls_cfg_rel"]
1090 if {![file exists $hls_cfg_file]} {
1091 Msg Error "HLS config file not found: $hls_cfg_file (from HLS_CONFIG=$hls_cfg_rel)"
1095 Msg Info " HLS config: $hls_cfg_file"
1097 # Validate the config file
1098 set error_msg "Failed to validate HLS config for $component_name"
1099 if {![ExecuteVitisUnifiedCommand $python_script "validate" \
1100 [list $hls_cfg_file] \
1102 Msg Error $error_msg
1106 # Create Vitis workspace with HLS component for GUI compatibility
1107 set hls_work_dir [file normalize "$ws_dir/hls_$component_name"]
1108 Msg Info "Creating Vitis HLS workspace component '$component_name' in $ws_dir ..."
1109 if {![ExecuteVitisUnifiedCommand $python_script "create_workspace" \
1110 [list $ws_dir $component_name $hls_cfg_file $hls_work_dir] \
1111 "Failed to create HLS workspace for $component_name"]} {
1112 Msg Warning "Could not create Vitis workspace for HLS component '$component_name'"
1115 Msg Info "HLS component '$component_name' configured successfully"
1117 Msg Warning "Invalid HLS key format: $hls_key. Expected format: hls:<name>"
1126 current_run -implementation [get_runs impl_1]
1133 Msg Info "Running report_ip_status, before upgrading and handling IPs..."
1136 if {$globalSettings::HOG_IP_PATH != ""} {
1137 set ip_repo_path $globalSettings::HOG_IP_PATH
1138 Msg Info "HOG_IP_PATH is set, will pull/push synthesised IPs from/to $ip_repo_path."
1140 lassign [
CheckRemoteIpPath $globalSettings::repo_path $ip_repo_path] system_ready on_eos on_rclone rclone_config_path
1141 if {$system_ready == 1} {
1143 HandleIP pull [get_property IP_FILE $ip] $ip_repo_path $globalSettings::repo_path [get_property IP_OUTPUT_DIR $ip]\
1144 $on_eos $on_rclone $rclone_config_path
1148 Msg Info "HOG_IP_PATH not set, will not push/pull synthesised IPs."
1152 proc SetGlobalVar {var {default_value HOG_NONE}} {
1154 if {[
info exists ::$var]} {
1155 Msg Debug "Setting $var to [subst $[subst ::$var]]"
1157 set globalSettings::$var [subst $[subst ::$var]]
1158 }
elseif {$default_value == "HOG_NONE"} {
1159 Msg Error "Mandatory variable $var was not defined. Please define it in hog.conf or in project tcl script."
1161 Msg Info "Setting $var to default value: \"$default_value\""
1163 set globalSettings::$var $default_value
1169 proc CreateProject {args} {
1174 if {[
catch {
package require cmdline} ERROR]} {
1175 puts "ERROR: If you are running this script on tclsh, you can fix this by installing 'tcllib'"
1179 {simlib_path.arg "" "Path of simulation libs"}
1180 {verbose "If set, launch the script in verbose mode."}
1181 {xsa.arg "" "xsa for creating platforms without a defined hw."}
1182 {vivado_only "If set, and project is vivado-vitis, vitis project will not be created."}
1183 {vitis_only "If set, and project is vivado-vitis, only vitis project will be created."}
1186 set usage "Create Vivado/Vitis/ISE/Quartus/Libero/Diamond project.\nUsage: CreateProject \[OPTIONS\] <project> <repository path>\n Options:"
1188 if {[
catch {
array set options [
cmdline::getoptions args $parameters $usage]}] || [
llength $args] < 2 || [
lindex $args 0] eq ""} {
1193 set globalSettings::DESIGN [
lindex $args 0]
1194 if {[
file exists [
lindex $args 1]]} {
1195 set globalSettings::repo_path [
file normalize [
lindex $args 1]]
1197 Msg Error "The second argument, [
lindex $args 1], should be the repository path."
1199 set globalSettings::tcl_path $globalSettings::repo_path/Hog/Tcl
1202 if {$options(verbose) == 1} {
1203 variable ::DEBUG_MODE 1
1207 if {$options(simlib_path) != ""} {
1209 set globalSettings::simlib_path "$options(simlib_path)"
1211 set globalSettings::simlib_path "${globalSettings::repo_path}/$options(simlib_path)"
1213 Msg Info "Simulation library path set to $options(simlib_path)"
1215 set globalSettings::simlib_path "${globalSettings::repo_path}/SimulationLib"
1216 Msg Info "Simulation library path set to default ${globalSettings::repo_path}/SimulationLib"
1222 set build_dir_name "Projects"
1223 set globalSettings::group_name [
file dirname ${globalSettings::DESIGN}]
1224 set globalSettings::project_name ${globalSettings::DESIGN}
1225 set globalSettings::pre_synth_file "pre-synthesis.tcl"
1226 set globalSettings::post_synth_file "post-synthesis.tcl"
1227 set globalSettings::pre_impl_file "pre-implementation.tcl"
1228 set globalSettings::post_impl_file "post-implementation.tcl"
1229 set globalSettings::pre_bit_file "pre-bitstream.tcl"
1230 set globalSettings::post_bit_file "post-bitstream.tcl"
1231 set globalSettings::quartus_post_module_file "quartus-post-module.tcl"
1232 set globalSettings::top_path "${globalSettings::repo_path}/Top/${globalSettings::DESIGN}"
1233 set globalSettings::list_path "${globalSettings::top_path}/list"
1234 set globalSettings::build_dir "${globalSettings::repo_path}/${build_dir_name}/${globalSettings::DESIGN}"
1235 set globalSettings::DESIGN [
file tail ${globalSettings::DESIGN}]
1236 set globalSettings::top_name [
file tail ${globalSettings::DESIGN}]
1237 set globalSettings::top_name [
file rootname ${globalSettings::top_name}]
1238 set globalSettings::synth_top_module "top_${globalSettings::top_name}"
1239 set globalSettings::user_ip_repo ""
1241 set globalSettings::pre_synth [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::pre_synth_file}"]
1242 set globalSettings::post_synth [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::post_synth_file}"]
1243 set globalSettings::pre_impl [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::pre_impl_file}"]
1244 set globalSettings::post_impl [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::post_impl_file}"]
1245 set globalSettings::pre_bit [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::pre_bit_file}"]
1246 set globalSettings::post_bit [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::post_bit_file}"]
1247 set globalSettings::quartus_post_module [
file normalize "${globalSettings::tcl_path}/integrated/${globalSettings::quartus_post_module_file}"]
1248 set globalSettings::LIBERO_MANDATORY_VARIABLES {"FAMILY" "PACKAGE" "DIE" }
1250 set proj_dir [
file normalize "${globalSettings::repo_path}/Top/${globalSettings::project_name}"]
1251 Msg Debug "Calling GetConfFiles with proj_dir=$proj_dir (project_name=${globalSettings::project_name})"
1252 lassign [
GetConfFiles $proj_dir] conf_file sim_file pre_file post_file pre_rtl_file
1255 if {[
file exists $conf_file]} {
1256 Msg Info "Parsing configuration file $conf_file..."
1263 if {$conf_version != "0.0.0"} {
1264 set globalSettings::a_v [
split $actual_version "."]
1265 set globalSettings::c_v [
split $conf_version "."]
1267 if {[
llength $globalSettings::a_v] < 2} {
1268 Msg Error "Couldn't parse IDE version: $actual_version."
1269 }
elseif {[
llength $globalSettings::a_v] == 2} {
1270 lappend globalSettings::a_v 0
1272 if {[
llength $globalSettings::c_v] < 2} {
1273 Msg Error "Wrong version format in hog.conf: $conf_version."
1274 }
elseif {[
llength $globalSettings::c_v] == 2} {
1275 lappend globalSettings::c_v 0
1280 Msg Info "Project version and $ide version match: $conf_version."
1281 }
elseif {$comp == 1} {
1282 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\
1283 If you want update this project to version $actual_version, please update the configuration file."
1286 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."
1289 Msg CriticalWarning "No version found in the first line of $conf_file. \
1290 It is HIGHLY recommended to replace the first line of $conf_file with: \#$ide $actual_version"
1293 if {$globalSettings::vitis_classic == 1} {
1295 Msg Error "Vitis Classic flow is not supported for versions < 2020.2. Please use Vitis 2020.2 or newer."}
1297 if {$globalSettings::vitis_unified == 1} {
1299 Msg Error "Vitis Unified flow is not supported for versions < 2019.2. Please use Vitis 2019.2 or newer."}
1302 if {[dict exists $globalSettings::PROPERTIES main]} {
1303 set main [dict get $globalSettings::PROPERTIES main]
1304 dict for {p v} $main {
1305 # notice the dollar in front of p: creates new variables and fill them with the value
1306 Msg Info "Main property $p set to $v"
1311 Msg Error "No main section found in $conf_file, make sure it has a section called \[main\] containing the mandatory properties."
1314 Msg Error "$conf_file was not found in your project directory, please create one."
1340 if {[
info exists env(HOG_EXTERNAL_PATH)]} {
1341 set globalSettings::HOG_EXTERNAL_PATH $env(HOG_EXTERNAL_PATH)
1343 set globalSettings::HOG_EXTERNAL_PATH ""
1346 set user_hog_file "${globalSettings::repo_path}/Top/hog.tcl"
1347 if {[
file exists $user_hog_file]} {
1348 Msg Info "Sourcing user hog.tcl file..."
1349 source $user_hog_file
1352 if {[
file exists $pre_file]} {
1353 Msg Info "Found pre-creation Tcl script $pre_file, executing it..."
1357 if {[
info exists env(HOG_IP_PATH)]} {
1358 set globalSettings::HOG_IP_PATH $env(HOG_IP_PATH)
1360 set globalSettings::HOG_IP_PATH ""
1367 set has_hls [
expr {[dict size [dict filter $globalSettings::PROPERTIES key {hls:*}]] > 0}]
1368 set has_platforms [
expr {[dict size [dict filter $globalSettings::PROPERTIES key {platform:*}]] > 0}]
1369 set has_apps [
expr {[dict size [dict filter $globalSettings::PROPERTIES key {app:*}]] > 0}]
1372 Msg Info "Found HLS component(s) in configuration, configuring HLS..."
1376 if {!$has_platforms && !$has_apps} {
1377 Msg Info "vitis unified HLS-only project, skipping Vivado project setup."
1381 if {$has_platforms || $has_apps} {
1382 set xsa_path $options(xsa)
1384 if {$xsa_path == ""} {
1385 if {[
string match "vivado_*" [
string tolower $ide]]} {
1387 set xpr_file [
file normalize "$globalSettings::build_dir/[
file tail $globalSettings::DESIGN].xpr"]
1388 if {[
file exists $xpr_file]} {
1389 Msg Info "Opening existing Vivado project to generate pre-synth XSA..."
1390 open_project $xpr_file
1391 set xsa_path [
file normalize "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"]
1393 write_hw_platform -fixed -force -file $xsa_path
1394 Msg Info "Pre-synth XSA generated: $xsa_path"
1398 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."
1403 Msg Error "This is a $ide only project with platform/app sections, an XSA file must be provided via the -xsa option."
1408 Msg Info "Configuring platforms with XSA: $xsa_path"
1412 if {[
file exists $post_file]} {
1413 if {[
string match "vivado_*" [
string tolower $ide]]} {
1414 Msg Info "Skipping post-creation.tcl in -vitis_only pass for $ide \
1415 (already executed during Vivado project creation)."
1417 Msg Info "Found post-creation Tcl script $post_file, executing it..."
1427 if {([
string tolower $ide] eq "vitis_classic" || [
string tolower $ide] eq "vitis_unified") && $options(vitis_only) == 1} {
1428 if {$options(xsa) == ""} {
1429 Msg Error "This is a $ide only project, an XSA file must be provided via -xsa option."
1447 set fileName_old [
file normalize "./hogTmp/.hogQsys.md5"]
1448 set fileDir [
file normalize "${globalSettings::build_dir}/.hog/"]
1450 set fileName_new [
file normalize "$fileDir/.hogQsys.md5"]
1451 if {[
file exists $fileName_new]} {
1452 file delete $fileName_new
1454 if {[
file exists $fileName_old]} {
1455 file rename -force $fileName_old $fileName_new
1456 file delete -force -- "./hogTmp"
1460 if {[
file exists $post_file]} {
1461 Msg Info "Found post-creation Tcl script $post_file, executing it..."
1465 build_design_hierarchy
1472 -ext_path "$globalSettings::HOG_EXTERNAL_PATH" \
1473 -list_files ".src,.ext" \
1474 "$globalSettings::repo_path/Top/$globalSettings::project_name/list/" \
1475 $globalSettings::repo_path] \
1476 listLibraries listProperties listSrcSets
1479 -ext_path "$globalSettings::HOG_EXTERNAL_PATH" \
1480 -list_files ".con" \
1481 "$globalSettings::repo_path/Top/$globalSettings::project_name/list/" \
1482 $globalSettings::repo_path] \
1483 listConstraints listConProperties listConSets
1486 -ext_path "$globalSettings::HOG_EXTERNAL_PATH" \
1487 -list_files ".sim" \
1488 "$globalSettings::repo_path/Top/$globalSettings::project_name/list/" \
1489 $globalSettings::repo_path] \
1490 listSimLibraries listSimProperties listSimSets
1493 cd $globalSettings::build_dir
1499 cd $globalSettings::repo_path
1503 [
file normalize $globalSettings::repo_path/Top/$globalSettings::project_name] \
1504 $globalSettings::repo_path \
1505 $globalSettings::HOG_EXTERNAL_PATH
1506 ] commit version hog_hash hog_ver top_hash top_ver libs hashes vers cons_ver cons_hash ext_names ext_hashes \
1507 xml_hash xml_ver user_ip_repos user_ip_hashes user_ip_vers
1512 set commit $this_commit
1515 if {$xml_hash != ""} {
1524 $globalSettings::repo_path \
1525 $globalSettings::project_name \
1526 $date $timee $commit $version \
1527 $top_hash $top_ver $hog_hash $hog_ver \
1528 $cons_ver $cons_hash $libs $vers $hashes \
1529 $ext_names $ext_hashes $user_ip_repos $user_ip_vers \
1530 $user_ip_hashes $flavour $xml_ver $xml_hash
1543 if {($globalSettings::vitis_classic == 1 || $globalSettings::vitis_unified == 1)} {
1546 write_hw_platform -fixed -force -file [
file normalize "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"]
1548 if {$options(xsa) == ""} {
1549 set presynth_xsa [
file normalize "$globalSettings::build_dir/$globalSettings::DESIGN-presynth.xsa"]
1550 set xsa_opt "-xsa $presynth_xsa"
1553 set xsa_opt "-xsa $options(xsa)"
1555 set xsa_opt "-xsa $globalSettings::repo_path/$options(xsa)"
1559 if {$globalSettings::vitis_classic == 1} {
1561 set xsct_cmd "xsct $globalSettings::tcl_path/launch.tcl C $xsa_opt -vitis_only $globalSettings::project_name"
1562 Msg Info "Running Vitis Classic project creation script with command: $xsct_cmd"
1563 set ret [
catch {
exec -ignorestderr {*}$xsct_cmd >@ stdout} result]
1565 Msg Error "xsct (vitis classic) returned an error state."
1567 }
elseif {$globalSettings::vitis_unified == 1} {
1569 set vivado_cmd "vivado -nojournal -nolog -mode batch -notrace \
1570 -source $globalSettings::tcl_path/launch.tcl \
1571 -tclargs C $xsa_opt -vitis_only $globalSettings::project_name"
1572 Msg Info "Running Vitis Unified project creation script with command: $vivado_cmd"
1573 set ret [
catch {
exec -ignorestderr {*}$vivado_cmd >@ stdout} result]
1575 Msg Error "vivado (vitis unified) returned an error state."
1581 Msg Info "Project $globalSettings::project_name created successfully in [
Relative $globalSettings::repo_path $globalSettings::build_dir]."
1582 Notify Info "Created project $globalSettings::project_name."