23 set default_commands {
26 Msg Status "\n** The projects in this repository are:"
27 ListProjects $repo_path $list_all
31 # DESCRIPTION: List the projects in the repository. To show hidden projects use the -all option
32 # OPTIONS: all, verbose
39 # DESCRIPTION: Display this help message or specific help for each directive
47 # DESCRIPTION: Create the project, replace it if already existing.
48 # OPTIONS: ext_path.arg, lib.arg, vivado_only, verbose
51 \^I(MPL(EMENT(ATION)?)?)?$ {#
52 set do_implementation 1
55 # NAME: IMPLEMENTATION or I
56 # DESCRIPTION: Runs only the implementation, the project must already exist and be synthesised.
57 # OPTIONS: check_syntax, ext_path.arg, njobs.arg, no_bitstream, no_reset, recreate, verbose
60 \^SYNT(H(ESIS(E)?)?)? {#
64 # DESCRIPTION: Run synthesis only, create the project if not existing.
65 # OPTIONS: check_syntax, ext_path.arg, njobs.arg, recreate, verbose
68 \^S(IM(ULAT(ION|E)?)?)?$ {#
71 # NAME*: SIMULATION or S
72 # DESCRIPTION: Simulate the project, creating it if not existing, unless it is a GHDL simulation.
73 # OPTIONS: check_syntax, compile_only, ext_path.arg, lib.arg, recreate, scripts_only, simset.arg, verbose
77 set do_implementation 1
82 # NAME*: WORKFLOW or W
83 # DESCRIPTION: Runs the full workflow, creates the project if not existing.
84 # OPTIONS: bitstream_only, check_syntax, ext_path.arg, impl_only, njobs.arg, no_bitstream, recreate, synth_only, verbose, vitis_only, xsa.arg
87 \^(CREATEWORKFLOW|CW)?$ {#
88 set do_implementation 1
94 # NAME: CREATEWORKFLOW or CW
95 # DESCRIPTION: Creates the project -even if existing- and launches the complete workflow.
96 # OPTIONS: check_syntax, ext_path.arg, njobs.arg, no_bitstream, synth_only, verbose, vivado_only, vitis_only, xsa.arg
99 \^(CHECKSYNTAX|CS)?$ {#proj
100 set do_check_syntax 1
101 # NAME: CHECKSYNTAX or CS
102 # DESCRIPTION: Check the syntax of the project. Only for Vivado, Quartus and Libero projects.
103 # OPTIONS: ext_path.arg, recreate, verbose
106 ^(IPB(US)?)|(X(ML)?)$ {#proj
109 # DESCRIPTION: Copy, check or create the IPbus XMLs for the project.
110 # OPTIONS: dst_dir.arg, generate, verbose
114 set do_list_file_parse 1
116 # DESCRIPTION: Print Hog list file contents in a tree-like fashon.
120 \^(CHECKYAML|YML)?$ {
123 set do_check_yaml_ref 1
124 # NAME: CHECKYML or YML
125 # DESCRIPTION: Check that the ref to Hog repository in the .gitlab-ci.yml file, matches the one in Hog submodule.
134 # DESCRIPTION: Add Hog buttons to the Vivado GUI, to check and recreate Hog list and configuration files.
138 \^(CHECKLIST|CL)?$ {#proj
139 set do_check_list_files 1
140 # NAME: CHECKLIST or CL
141 # DESCRIPTION: Check that list and configuration files on disk match what is on the project.
142 # OPTIONS: ext_path.arg, verbose
147 set argument_is_no_project 1
148 # NAME: COMPSIMLIB or COMPSIM
149 # DESCRIPTION: Compiles the simulation library for the chosen simulator with Vivado.
150 # OPTIONS: dst_dir.arg, verbose
155 # NAME: RTL or RTLANALYSIS
156 # DESCRIPTION: Elaborate the RTL analysis report for the chosen project.
157 # OPTIONS: check_syntax, recreate, verbose
162 # NAME: SIGASI or SIG
163 # DESCRIPTION: Create a .csv file to be used in Sigasi.
170 # DESCRIPTION: Print the design hierarchy for the chosen project.
171 # OPTIONS: compile_order, ext_path.arg, ignore.arg, include_gen_prods, include_ieee, light, output.arg, top.arg, verbose
175 if {$directive != ""} {
176 set NO_DIRECTIVE_FOUND 1
192 {no_bitstream "If set, the bitstream file will not be produced."}
193 {recreate "If set, the project will be re-created if it already exists."}
194 {no_reset "If set, runs (synthesis and implementation) won't be reset before launching them."}
195 {check_syntax "If set, the HDL syntax will be checked at the beginning of the workflow."}
196 {njobs.arg 4 "Number of jobs. Default: 4"}
197 {ext_path.arg "" "Sets the absolute path for the external libraries."}
198 {lib.arg "" "Simulation library path, compiled or to be compiled"}
199 {synth_only "If set, only the synthesis will be performed."}
200 {impl_only "If set, only the implementation will be performed. This assumes synthesis was already done."}
201 {scripts_only "If set, the simulation scripts will be generated, but the simulation will not be run."}
202 {compile_only "If set, the simulation libraries will be compiled, but not run."}
203 {bitstream_only "If set, only the bitstream will be produced. This assumes implementation was already done. For a Vivado-Vitis\
204 project this command can be used to generate the boot artifacts including the ELF file(s) without running the\
205 full Vivado workflow."}
206 {vivado_only "If set, and project is vivado-vitis, vitis project will not be created."}
207 {vitis_only "If set, and project is vivado-vitis create only vitis project. If an xsa is not given, a pre-synth xsa will be created."}
208 {xsa.arg "" "If set, and project is vivado-vitis, use this xsa for creating platforms without a defined hw."}
209 {simset.arg "" "Simulation sets, separated by commas, to be run."}
210 {all "List all projects, including test projects. Test projects have #test on the second line of hog.conf."}
211 {generate "For IPbus XMLs, it will re create the VHDL address decode files."}
212 {dst_dir.arg "" "For reports, IPbus XMLs, set the destination folder (default is in the ./bin folder)."}
213 {output.arg "" "For tree hierarchy mode, set the output file (default is console)."}
214 {top.arg "" "For tree hierarchy mode, set the top module (default is the top module defined in hog.conf)."}
215 {ignore.arg "" "For tree hierarchy mode, filter's the printed hierarchy to exclude modules that match the given string."}
216 {include_ieee "" "For tree hierarchy mode, include IEEE/STD libraries in the printed hierarchy. (Default 0)"}
217 {include_gen_prods "" "For tree hierarchy mode, include IP generated products in the printed hierarchy. (Default 0)"}
218 {compile_order "" "For tree hierarchy mode, prints compile order instead of hierarchy."}
219 {verbose "If set, launch the script in verbose mode"}
220 {light "For tree hierarchy mode, print a light version of the hierarchy (without file paths)."}
223 set tcl_path [
file normalize "[
file dirname [
info script]]"]
224 source $tcl_path/hog.tcl
225 source $tcl_path/create_project.tcl
230 set argv $quartus(args)
236 set commands_path [
file normalize "$tcl_path/../../hog-commands/"]
239 lassign [
InitLauncher $::argv0 $tcl_path $parameters $default_commands $argv $custom_commands] \
240 directive project project_name group_name repo_path old_path bin_dir top_path usage short_usage cmd ide list_of_options
242 array set options $list_of_options
244 if {$options(verbose) == 1} {
247 Msg Debug "Returned by InitLauncher: \n\
248 - project: $project \n\
249 - project_name $project_name \n\
250 - group_name $group_name \n\
251 - repo_path $repo_path \n\
252 - old_path $old_path \n\
253 - bin_dir $bin_dir \n\
254 - top_path $top_path \n\
258 if {$options(ext_path) != ""} {
259 set ext_path $options(ext_path)
268 if {$options(output) != ""} {
269 set output_path $options(output)
272 set light_hierarchy $options(light)
273 set ignored_hierarchy $options(ignore)
274 set top_module $options(top)
275 set compile_order $options(compile_order)
276 set include_ieee $options(include_ieee)
277 set include_gen_prods $options(include_gen_prods)
281 set do_implementation 0
set do_synthesis 0
set do_bitstream 0
282 set do_create 0
set do_compile 0
set do_simulation 0
set recreate 0
283 set do_reset 1
set do_list_all 2
set do_check_syntax 0
set do_vitis_build 0
284 set scripts_only 0
set compile_only 0
290 set do_list_file_parse 0
291 set do_check_yaml_ref 0
293 set do_check_list_files 0
298 set NO_DIRECTIVE_FOUND 0
299 Msg Debug "Looking for a $directive in : $default_commands"
300 switch -regexp -- $directive $default_commands
302 if {$NO_DIRECTIVE_FOUND == 1} {
303 Msg Debug "No directive found in default commands, looking in custom commands..."
304 if {[
string length $custom_commands] > 0 && [dict exists $custom_commands $directive]} {
305 Msg Debug "Directive $directive found in custom commands."
306 if {$cmd == "custom_tcl"} {
307 eval [dict get $custom_commands $directive SCRIPT]
311 Msg Info "Launching command: $cmd..."
314 set ret [
catch {
exec which $ide}]
316 Msg Error "$ide not found in your system. Make sure to add $ide to your PATH enviromental variable."
320 if {[
string first libero $cmd] >= 0} {
323 set libero_script [open "launch-libero-hog.sh" w]
324 puts $libero_script "#!/bin/sh"
325 puts $libero_script $cmd
327 set cmd "sh launch-libero-hog.sh"
330 set ret [
catch {
exec -ignorestderr {*}$cmd >@ stdout} result]
333 Msg Error "IDE returned an error state."
339 if {[
string first libero $cmd] >= 0} {
340 file delete "launch-libero-hog.sh"
346 eval [dict get $custom_commands $directive SCRIPT]
348 set no_exit [dict get $custom_commands $directive NO_EXIT]
354 Msg Info "No directive found, pre ide exiting..."
355 Msg Status "ERROR: Unknown directive $directive.\n\n"
361 if {$options(all) == 1} {
367 if {$options(dst_dir) == "" && ($do_ipbus_xml == 1 || $do_check_list_files == 1) && $project != ""} {
369 lassign [
GetRepoVersions [
file normalize $repo_path/Top/$group_name/$project] \
370 $repo_path $ext_path] commit version hog_hash hog_ver top_hash top_ver libs hashes vers \
371 cons_ver cons_hash ext_names ext_hashes xml_hash xml_ver user_ip_repos \
372 user_ip_hashes user_ip_vers
376 set dst_dir [
file normalize "$repo_path/bin/$group_name/$project\-$describe"]
381 Msg Status "\n\nPossible projects are:"
385 }
elseif {$cmd == -2} {
387 Msg Status "ERROR: You must specify a project with directive $directive."
389 Msg Status "Possible projects are:"
392 }
elseif {$cmd == 0} {
394 Msg Info "$::argv0 was launched from the IDE."
406 if {$do_ipbus_xml == 1} {
407 Msg Info "Handling IPbus XMLs for $project_name..."
409 set proj_dir $repo_path/Top/$project_name
411 if {$options(generate) == 1} {
417 if {$options(dst_dir) != ""} {
418 set dst_dir $options(dst_dir)
420 set xml_dst "$dst_dir/xml"
423 if {[
llength [glob -nocomplain $proj_dir/list/*.ipb]] > 0} {
424 if {![
file exists $xml_dst]} {
425 Msg Info "$xml_dst directory not found, creating it..."
429 Msg Error "No .ipb files found in $proj_dir/list/"
434 set sha [
lindex $ret 13]
435 set hex_ver [
lindex $ret 14]
438 CopyIPbusXMLs $proj_dir $repo_path $xml_dst $ver $sha 1 $xml_gen
443 if {$do_list_file_parse == 1} {
444 set proj_dir $repo_path/Top/$project_name
445 set proj_list_dir $repo_path/Top/$project_name/list
446 GetHogFiles -print_log -list_files {.src,.con,.sim,.ext,.ipb} $proj_list_dir $repo_path
452 if {$do_hierarchy == 1} {
453 source $tcl_path/utils/hierarchy.tcl
454 set proj_dir $repo_path/Top/$project_name
455 set proj_list_dir $repo_path/Top/$project_name/list
457 -list_files ".src,.ext" $proj_list_dir $repo_path]\
458 listLibraries listProperties listSrcSets
459 Hierarchy $listProperties $listLibraries $repo_path $output_path $compile_order \
460 $light_hierarchy $top_module $ignored_hierarchy $include_ieee $include_gen_prods
463 if {$do_sigasi == 1} {
465 Msg Info "Creating Sigasi CSV files for project $project_name..."
466 set proj_dir $repo_path/Top/$project_name
467 set proj_list_dir $repo_path/Top/$project_name/list
468 set project [
file tail $project_name]
469 lassign [
GetHogFiles -list_files {.src} $proj_list_dir $repo_path] libraries
470 set csv_file [open "sigasi_$project.csv" w]
471 foreach lib $libraries {
472 set source_files [
DictGet $libraries $lib]
473 foreach source_file $source_files {
474 if {[
file extension $source_file] == ".vhd" ||
475 [
file extension $source_file] == ".vhdl" ||
476 [
file extension $source_file] == ".sv" ||
477 [
file extension $source_file] == ".v" } {
478 puts $csv_file [
concat [
file rootname $lib] "," $source_file]
483 Msg Info "Sigasi CSV file created: sigasi_$project.csv"
484 Msg Info "You can use the python script provided by Sigasi to convert the generated csv file into a Sigasi project."
485 Msg Info "More info at: https://www.sigasi.com/knowledge/how_tos/generating-sigasi-project-vivado-project/#2-generate-the-sigasi-project-files-from-the-csv-file"
489 if {$do_check_yaml_ref == 1} {
490 Msg Info "Checking if \"ref\" in .gitlab-ci.yml actually matches the included yml file in Hog submodule"
495 if {$do_buttons == 1} {
496 Msg Info "Adding Hog buttons to Vivado bar (will use the vivado currently in PATH)..."
498 set cmd "vivado -mode batch -notrace -source $repo_path/Hog/Tcl/utils/add_hog_custom_button.tcl"
501 if {$do_compile_lib == 1} {
502 if {$project eq ""} {
503 Msg Error "You need to specify a simulator as first argument."
506 set simulator $project
507 Msg Info "Selecting $simulator simulator..."
509 if {$options(dst_dir) != ""} {
510 set output_dir $options(dst_dir)
512 Msg Info "No destination directory defined. Using default: SimulationLib/"
513 set output_dir "SimulationLib"
517 set cmd "vivado -mode batch -notrace -source $repo_path/Hog/Tcl/utils/compile_simlib.tcl -tclargs -simulator $simulator -output_dir $output_dir"
521 if {$do_simulation == 1} {
523 set ghdl_simsets [
GetSimSets $project_name $repo_path "$options(simset)" 1]
525 dict for {simset_name simset_dict} $ghdl_simsets {
526 if {$ghdl_import == 0} {
527 ImportGHDL $project_name $repo_path $simset_name $simset_dict $ext_path
530 LaunchGHDL $project_name $repo_path $simset_name $simset_dict $ext_path
531 # dict unset simsets_dict $simset_name
533 set ide_simsets [
GetSimSets $project_name $repo_path $options(simset) 0 1]
535 if {[dict size $ide_simsets] == 0} {
537 Msg Info "All simulations have been run, exiting..."
550 Msg Info "Launching command: $cmd..."
553 set ret [
catch {
exec which $ide}]
555 Msg Error "$ide not found in your system. Make sure to add $ide to your PATH enviromental variable."
559 if {[
string first libero $cmd] >= 0} {
562 set libero_script [open "launch-libero-hog.sh" w]
563 puts $libero_script "#!/bin/sh"
564 puts $libero_script $cmd
566 set cmd "sh launch-libero-hog.sh"
569 set ret [
catch {
exec -ignorestderr {*}$cmd >@ stdout} result]
572 Msg Error "IDE returned an error state."
578 if {[
string first libero $cmd] >= 0} {
579 file delete "launch-libero-hog.sh"
591 if {[
info exists env(HOG_TCLLIB_PATH)]} {
592 lappend auto_path $env(HOG_TCLLIB_PATH)
594 puts "ERROR: To run Hog with Microsemi Libero SoC or Lattice Diamond,\
595 you need to define the HOG_TCLLIB_PATH variable."
600 if {[
catch {
package require cmdline} ERROR] || [
catch {
package require struct::matrix} ERROR]} {
601 puts "$ERROR\n Tcllib not found. If you are running this script on tclsh for debuggin purpose ONLY, you can fix this by installing 'tcllib'"
605 set run_folder [
file normalize "$repo_path/Projects/$project_name/$project.runs/"]
607 set run_folder [
file normalize "$repo_path/Projects/$project_name/"]
611 set project_path [
file normalize "$repo_path/Projects/$project_name/"]
616 set ide_name [
lindex [regexp -all -inline {\S+} $ide_name_and_ver] 0]
618 if {$options(no_bitstream) == 1} {
623 if {$options(recreate) == 1} {
627 if {$options(synth_only) == 1} {
628 set do_implementation 0
635 if {$options(impl_only) == 1} {
636 set do_implementation 1
644 if {$options(vitis_only) == 1 || $ide_name eq "vitis_classic"} {
646 set do_implementation 0
653 if {$options(bitstream_only) == 1} {
654 set do_bitstream_only 1
656 set do_implementation 0
661 set do_bitstream_only 0
664 if {$options(vivado_only) == 1} {
668 if {$options(no_reset) == 1} {
672 if {$options(check_syntax) == 1} {
673 set do_check_syntax 1
676 if {$options(scripts_only) == 1} {
680 if {$options(compile_only) == 1} {
686 if {$options(lib) != ""} {
687 set lib_path [
file normalize $options(lib)]
689 if {[
info exists env(HOG_SIMULATION_LIB_PATH)]} {
690 set lib_path $env(HOG_SIMULATION_LIB_PATH)
692 if {[
file exists "$repo_path/SimulationLib"]} {
693 set lib_path [
file normalize "$repo_path/SimulationLib"]
701 Msg Info "Number of jobs set to $options(njobs)."
709 set project_file [
file normalize $repo_path/Projects/$project_name/$project.ppr]
712 set project_file [
file normalize $repo_path/Projects/$project_name/$project.xpr]
715 set project_file [
file normalize $repo_path/Projects/$project_name/vitis_classic/.metadata/]
716 Msg Info "Setting project file for Vitis Classic project $project_name to $project_file"
718 if {[
catch {
package require ::quartus::project} ERROR]} {
719 Msg Error "$ERROR\n Can not find package ::quartus::project"
723 Msg Info "Loaded package ::quartus::project"
726 set project_file "$project_path/$project.qpf"
728 set project_file [
file normalize $repo_path/Projects/$project_name/$project.prjx]
731 set project_file [
file normalize $repo_path/Projects/$project_name/$project.ldf]
734 if {[
file exists $project_file]} {
735 Msg Info "Found project file $project_file for $project_name."
738 Msg Info "Project file not found for $project_name."
742 if {($proj_found == 0 || $recreate == 1)} {
743 Msg Info "Creating (possibly replacing) the project $project_name..."
744 Msg Debug "launch.tcl: calling GetConfFiles with $repo_path/Top/$project_name"
745 lassign [
GetConfFiles $repo_path/Top/$project_name] conf sim pre post
747 if {[
file exists $conf]} {
749 if {$options(vivado_only) == 1} {
750 CreateProject -simlib_path $lib_path -xsa $options(xsa) -vivado_only $project_name $repo_path
752 CreateProject -simlib_path $lib_path -xsa $options(xsa) $project_name $repo_path
754 Msg Info "Done creating project $project_name."
756 Msg Error "Project $project_name is incomplete: no hog.conf file found, please create one..."
759 Msg Info "Opening existing project file $project_file..."
761 file mkdir "$repo_path/Projects/$project_name/$project.gen/sources_1"
765 set vitis_workspace [
file normalize $repo_path/Projects/$project_name/vitis_classic/]
766 Msg Info "Setting workspace to $vitis_workspace"
767 setws $vitis_workspace
776 if {$do_check_syntax == 1} {
777 Msg Info "Checking syntax for project $project_name..."
787 if {$do_vitis_build == 1} {
791 set xsct_cmd "xsct $tcl_path/launch.tcl W -vitis_only $project_name"
792 set ret [
catch {
exec -ignorestderr {*}$xsct_cmd >@ stdout} result]
794 Msg Error "xsct (vitis classic) returned an error state."
800 if {$do_synthesis == 1} {
801 LaunchSynthesis $do_reset $do_create $run_folder $project_name $repo_path $ext_path $options(njobs)
804 if {$do_implementation == 1} {
805 LaunchImplementation $do_reset $do_create $run_folder $project_name $repo_path $options(njobs) $do_bitstream
808 if {$do_bitstream_only == 1 && [
IsXilinx]} {
810 }
elseif {$do_bitstream_only == 1 && ![
IsXilinx]} {
811 Msg Error "Bitstream only option is not supported for this IDE."
814 if {$do_bitstream == 1 && ![
IsXilinx]} {
818 if {$do_simulation == 1} {
820 set simsets [
GetSimSets $project_name $repo_path $options(simset)]
821 LaunchSimulation $project_name $lib_path $simsets $repo_path $scripts_only $compile_only
825 if {$do_check_list_files} {
826 Msg Info "Running list file checker..."
834 set argv0 check_list_files
835 if {$ext_path ne ""} {
836 set argv [list "-ext_path" "$ext_path" "-outDir" "$dst_dir" "-pedantic"]
838 set argv [list "-outDir" "$dst_dir" "-pedantic"]
841 source $tcl_path/utils/check_list_files.tcl