20 set default_commands {
23 Msg Status "\n** The projects in this repository are:"
24 ListProjects $repo_path $list_all
28 # DESCRIPTION: List the projects in the repository. To show hidden projects use the -all option
29 # OPTIONS: all, verbose
36 # DESCRIPTION: Display this help message or specific help for each directive
44 # DESCRIPTION: Create the project, replace it if already existing.
45 # OPTIONS: ext_path.arg, lib.arg, verbose
48 \^I(MPL(EMENT(ATION)?)?)?$ {#
49 set do_implementation 1
52 # NAME: IMPLEMENTATION or I
53 # DESCRIPTION: Runs only the implementation, the project must already exist and be synthesised.
54 # OPTIONS: check_syntax, ext_path.arg, njobs.arg, no_bitstream, no_reset, recreate, verbose
57 \^SYNT(H(ESIS(E)?)?)? {#
61 # DESCRIPTION: Run synthesis only, create the project if not existing.
62 # OPTIONS: check_syntax, ext_path.arg, njobs.arg, recreate, verbose
65 \^S(IM(ULAT(ION|E)?)?)?$ {#
68 # NAME*: SIMULATION or S
69 # DESCRIPTION: Simulate the project, creating it if not existing, unless it is a GHDL simulation.
70 # OPTIONS: check_syntax, ext_path.arg, lib.arg, recreate, simset.arg, verbose
74 set do_implementation 1
78 # NAME*: WORKFLOW or W
79 # DESCRIPTION: Runs the full workflow, creates the project if not existing.
80 # OPTIONS: check_syntax, ext_path.arg, impl_only, njobs.arg, no_bitstream, recreate, synth_only, verbose
83 \^(CREATEWORKFLOW|CW)?$ {#
84 set do_implementation 1
89 # NAME: CREATEWORKFLOW or CW
90 # DESCRIPTION: Creates the project -even if existing- and launches the complete workflow.
91 # OPTIONS: check_syntax, ext_path.arg, njobs.arg, no_bitstream, synth_only, verbose
94 \^(CHECKSYNTAX|CS)?$ {#proj
96 # NAME: CECHSYNTAX or CS
97 # DESCRIPTION: Check the syntax of the project. Only for Vivado, Quartus and Libero projects.
98 # OPTIONS: ext_path.arg, recreate, verbose
104 # DESCRIPTION: Copy, check or create the IPbus XMLs for the project.
105 # OPTIONS: dst_dir.arg, generate, verbose
109 set do_list_file_parse 1
111 # DESCRIPTION: Print Hog list file contents in a tree-like fashon.
115 \^(CHECKYAML|YML)?$ {
118 set do_check_yaml_ref 1
119 # NAME: CHECKYML or YML
120 # DESCRIPTION: Check that the ref to Hog repository in the .gitlab-ci.yml file, matches the one in Hog submodule.
129 # DESCRIPTION: Add Hog buttons to the Vivado GUI, to check and recreate Hog list and configuration files.
133 \^(CHECKLIST|CL)?$ {#proj
134 set do_check_list_files 1
135 # NAME: CHECKLIST or CL
136 # DESCRIPTION: Check that list and configuration files on disk match what is on the project.
137 # OPTIONS: ext_path.arg, verbose
142 set argument_is_no_project 1
143 # NAME: COMPSIMLIB or COMPSIM
144 # DESCRIPTION: Compiles the simulation library for the chosen simulator with Vivado.
145 # OPTIONS: dst_dir.arg, verbose
150 # NAME: SIGASI or SIG
151 # DESCRIPTION: Create a .csv file to be used in Sigasi.
156 if {$directive != ""} {
157 Msg Status "ERROR: Unknown directive $directive.\n\n"
175 {no_bitstream "If set, the bitstream file will not be produced."}
176 {recreate "If set, the project will be re-created if it already exists."}
177 {no_reset "If set, runs (synthesis and implementation) won't be reset before launching them."}
178 {check_syntax "If set, the HDL syntax will be checked at the beginning of the workflow."}
179 {njobs.arg 4 "Number of jobs. Default: 4"}
180 {ext_path.arg "" "Sets the absolute path for the external libraries."}
181 {lib.arg "" "Simulation library path, compiled or to be compiled"}
182 {synth_only "If set, only the synthesis will be performed."}
183 {impl_only "If set, only the implementation will be performed. This assumes synthesis should was already done."}
184 {simset.arg "" "Simulation sets, separated by commas, to be run."}
185 {all "List all projects, including test projects. Test projects have #test on the second line of hog.conf."}
186 {generate "For IPbus XMLs, it will re create the VHDL address decode files."}
187 {dst_dir.arg "" "For reports, IPbus XMLs, set the destination folder (default is in the ./bin folder)."}
188 {verbose "If set, launch the script in verbose mode"}
191 set tcl_path [
file normalize "[
file dirname [
info script]]"]
192 source $tcl_path/hog.tcl
193 source $tcl_path/create_project.tcl
197 set argv $quartus(args)
200 Msg Debug "s: $::argv0 a: $argv"
202 set commands_path [
file normalize "$tcl_path/../../hog-commands/"]
208 lassign [
InitLauncher $::argv0 $tcl_path $parameters $default_commands $argv $custom_usage] directive project project_name group_name repo_path old_path bin_dir top_path usage short_usage cmd ide list_of_options
209 array set options $list_of_options
210 Msg Debug "Returned by InitLauncher: \
211 $project $project_name $group_name $repo_path $old_path $bin_dir $top_path $cmd"
214 if { $options(ext_path) != ""} {
215 set ext_path $options(ext_path)
221 set do_implementation 0
set do_synthesis 0
set do_bitstream 0
222 set do_create 0
set do_compile 0
set do_simulation 0
set recreate 0
223 set do_reset 1
set do_list_all 2
set do_check_syntax 0
230 set do_list_file_parse 0
231 set do_check_yaml_ref 0
233 set do_check_list_files 0
237 Msg Debug "Looking for a $directive in : $default_commands $custom_commands"
238 switch -regexp -- $directive "$default_commands $custom_commands"
240 if { $options(all) == 1 } {
246 if {$options(dst_dir) == "" && ($do_ipbus_xml ==1 || $do_check_list_files == 1)} {
248 lassign [
GetRepoVersions [
file normalize $repo_path/Top/$group_name/$project] \
249 $repo_path $ext_path] commit version hog_hash hog_ver top_hash top_ver libs hashes vers \
250 cons_ver cons_hash ext_names ext_hashes xml_hash xml_ver user_ip_repos \
251 user_ip_hashes user_ip_vers
254 set dst_dir [
file normalize "bin/$group_name/$project\-$describe"]
259 Msg Status "\n\nPossible projects are:"
263 }
elseif {$cmd == -2} {
265 Msg Status "ERROR: You must specify a project with directive $directive."
267 Msg Status "Possible projects are:"
271 }
elseif {$cmd == 0} {
273 Msg Info "$::argv0 was launched from the IDE."
285 if {$do_ipbus_xml == 1} {
286 Msg Info "Handling IPbus XMLs for $project_name..."
288 set proj_dir $repo_path/Top/$project_name
290 if { $options(generate) == 1 } {
297 set xml_dst "$dst_dir/xml"
300 if {[
llength [glob -nocomplain $proj_dir/list/*.ipb]] > 0 } {
301 if {![
file exists $xml_dst]} {
302 Msg Info "$xml_dst directory not found, creating it..."
306 Msg Error "No .ipb files found in $proj_dir/list/"
311 set sha [
lindex $ret 13]
312 set hex_ver [
lindex $ret 14]
315 CopyIPbusXMLs $proj_dir $repo_path $xml_dst $ver $sha 1 $xml_gen
320 if {$do_list_file_parse == 1} {
321 set proj_dir $repo_path/Top/$project_name
322 set proj_list_dir $repo_path/Top/$project_name/list
323 GetHogFiles -print_log -list_files {.src,.con,.sim,.ext,.sim,.ipb} $proj_list_dir $repo_path
329 if {$do_check_yaml_ref == 1 } {
330 Msg Info "Checking if \"ref\" in .gitlab-ci.yml actually matches the included yml file in Hog submodule"
335 if {$do_buttons == 1 } {
336 Msg Info "Adding Hog buttons to Vivado bar (will use the vivado currently in PATH)..."
338 set cmd "vivado -mode batch -notrace -source $repo_path/Hog/Tcl/utils/add_hog_custom_button.tcl"
341 if {$do_compile_lib == 1} {
342 if {$project eq ""} {
343 Msg Error "You need to specify a simulator as first argument."
346 set simulator $project
347 Msg Info "Selecting $simulator simulator..."
349 if { $options(dst_dir) != "" } {
350 set output_dir $options(dst_dir)
352 Msg Info "No destination directory defined. Using default: SimulationLib/"
353 set output_dir "SimulationLib"
357 set cmd "vivado -mode batch -notrace -source $repo_path/Hog/Tcl/utils/compile_simlib.tcl -tclargs -simulator $simulator -output_dir $output_dir"
361 if {$do_simulation == 1} {
363 set ghdl_simsets [
GetSimSets $project_name $repo_path "$options(simset)" 1]
365 dict for {simset_name simset_dict} $ghdl_simsets {
366 if {$ghdl_import == 0} {
367 ImportGHDL $project_name $repo_path $simset_name $simset_dict $ext_path
370 LaunchGHDL $project_name $repo_path $simset_name $simset_dict $ext_path
371 # dict unset simsets_dict $simset_name
373 set ide_simsets [
GetSimSets $project_name $repo_path $options(simset) 0 1]
375 if {[dict size $ide_simsets] == 0} {
377 Msg Info "All simulations have been run, exiting..."
391 Msg Info "Launching command: $cmd..."
394 set ret [
catch {
exec which $ide}]
396 Msg Error "$ide not found in your system. Make sure to add $ide to your PATH enviromental variable."
400 if {[
string first libero $cmd] >= 0} {
403 set libero_script [open "launch-libero-hog.sh" w]
404 puts $libero_script "#!/bin/sh"
405 puts $libero_script $cmd
407 set cmd "sh launch-libero-hog.sh"
410 set ret [
catch {
exec -ignorestderr {*}$cmd >@ stdout} result]
413 Msg Error "IDE returned an error state."
419 if {[
string first libero $cmd] >= 0} {
420 file delete "launch-libero-hog.sh"
431 if {[
info exists env(HOG_TCLLIB_PATH)]} {
432 lappend auto_path $env(HOG_TCLLIB_PATH)
434 puts "ERROR: To run Hog with Microsemi Libero SoC or Lattice Diamond,\
435 you need to define the HOG_TCLLIB_PATH variable."
440 if {[
catch {
package require cmdline} ERROR] || [
catch {
package require struct::matrix} ERROR]} {
441 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'"
445 set run_folder [
file normalize "$repo_path/Projects/$project_name/$project.runs/"]
447 set run_folder [
file normalize "$repo_path/Projects/$project_name/"]
451 set project_path [
file normalize "$repo_path/Projects/$project_name/"]
454 if { $options(no_bitstream) == 1 } {
459 if { $options(recreate) == 1 } {
463 if { $options(synth_only) == 1} {
464 set do_implementation 0
471 if { $options(impl_only) == 1} {
472 set do_implementation 1
480 if { $options(no_reset) == 1 } {
484 if { $options(check_syntax) == 1 } {
485 set do_check_syntax 1
491 if {$options(lib)!= ""} {
492 set lib_path [
file normalize $options(lib)]
494 if {[
info exists env(HOG_SIMULATION_LIB_PATH)]} {
495 set lib_path $env(HOG_SIMULATION_LIB_PATH)
497 if {[
file exists "$repo_path/SimulationLib"]} {
498 set lib_path [
file normalize "$repo_path/SimulationLib"]
507 if { $options(verbose) == 1 } {
508 variable ::DEBUG_MODE 1
519 set project_file [
file normalize $repo_path/Projects/$project_name/$project.ppr]
522 set project_file [
file normalize $repo_path/Projects/$project_name/$project.xpr]
524 if { [
catch {
package require ::quartus::project} ERROR] } {
525 Msg Error "$ERROR\n Can not find package ::quartus::project"
529 Msg Info "Loaded package ::quartus::project"
532 set project_file "$project_path/$project.qpf"
534 set project_file [
file normalize $repo_path/Projects/$project_name/$project.prjx]
537 set project_file [
file normalize $repo_path/Projects/$project_name/$project.ldf]
540 if {[
file exists $project_file]} {
541 Msg Info "Found project file $project_file for $project_name."
544 Msg Info "Project file not found for $project_name."
548 if {($proj_found == 0 || $recreate == 1)} {
549 Msg Info "Creating (possibly replacing) the project $project_name..."
550 lassign [
GetConfFiles $repo_path/Top/$project_name] conf sim pre post
552 if {[
file exists $conf]} {
554 CreateProject -simlib_path $lib_path $project_name $repo_path
556 Msg Error "Project $project_name is incomplete: no hog.conf file found, please create one..."
559 Msg Info "Opening existing project file $project_file..."
561 file mkdir "$repo_path/Projects/$project_name/$project.gen/sources_1"
568 if { $do_check_syntax == 1 } {
569 Msg Info "Checking syntax for project $project_name..."
574 if {$do_synthesis == 1} {
575 LaunchSynthesis $do_reset $do_create $run_folder $project_name $repo_path $ext_path $options(njobs)
578 if {$do_implementation == 1 } {
579 LaunchImplementation $do_reset $do_create $run_folder $project_name $repo_path $options(njobs) $do_bitstream
583 if {$do_bitstream == 1 && ![
IsXilinx] } {
587 if {$do_simulation == 1} {
589 set simsets [
GetSimSets $project_name $repo_path $options(simset)]
594 if {$do_check_list_files} {
595 Msg Info "Running list file checker..."
603 set argv0 check_list_files
604 if {$ext_path ne ""} {
605 set argv [list "-ext_path" "$ext_path" "-outDir" "$dst_dir" "-pedantic"]
607 set argv [list "-outDir" "$dst_dir" "-pedantic"]
610 source $tcl_path/utils/check_list_files.tcl
615 Msg Info "Creating Sigasi file for $project..."
618 set csv_name "${project}_sigasi_sim.csv"
620 Msg Info "Generating IP targets for simulations..."
621 foreach ip [get_ips] {
622 set targets [list_targets [get_files [
file tail [get_property IP_FILE $ip]]]]
623 if { [ lsearch -exact $targets simulation] >= 0 } {
624 generate_target simulation $ip
626 Msg Warning "IP $ip is not a simulation target, skipping..."
631 set source_files [get_files -filter {(FILE_TYPE == VHDL || FILE_TYPE == "VHDL 2008" || FILE_TYPE == "VHDL 2019" || FILE_TYPE == VERILOG || FILE_TYPE == SYSTEMVERILOG) && USED_IN_SIMULATION == 1 }]
632 if {$options(dst_dir) == ""} {
633 set dst_path "$repo_path"
635 set dst_path $repo_path/$options(dst_dir)
636 if {![
file exists $dst_path]} {
637 Msg Info "Creating $dst_path..."
642 Msg Info "Creating sigasi csv file for simulation $dst_path/$csv_name..."
643 set csv_file [open $dst_path/$csv_name w]
645 foreach source_file $source_files {
646 puts $csv_file [
concat [ get_property LIBRARY $source_file] "," $source_file]
651 set csv_name "${project}_sigasi_synth.csv"
652 Msg Info "Generating IP targets for synthesis..."
653 foreach ip [get_ips] {
654 generate_target synthesis $ip
657 set source_files [get_files -filter {(FILE_TYPE == VHDL || FILE_TYPE == "VHDL 2008" || FILE_TYPE == "VHDL 2019" || FILE_TYPE == VERILOG || FILE_TYPE == SYSTEMVERILOG) && USED_IN_SYNTHESIS == 1 }]
658 Msg Info "Creating sigasi csv file for synthesis $dst_path/$csv_name..."
659 set csv_file [open $dst_path/$csv_name w]
660 foreach source_file $source_files {
661 puts $csv_file [
concat [ get_property LIBRARY $source_file] "," $source_file]