Hog Hog2026.1-3
launch.tcl
Go to the documentation of this file.
1 #!/usr/bin/env tclsh
2 # @file
3 # Copyright 2018-2026 The University of Birmingham
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 
17 
18 # Launch Xilinx Vivado or ISE implementation and possibly write bitstream in text mode
19 
20 # Developers Tip for new commands
21 # Add a hashtag sign # after the curly brake (e.g. \^C(REATE)?$ {# ...}) if the command requires a project name as an argument
22 
23 set default_commands {
24 
25  \^L(IST)?$ {
26  Msg Status "\n** The projects in this repository are:"
27  ListProjects $repo_path $list_all
28  Msg Status "\n"
29  exit 0
30  # NAME*: LIST or L
31  # DESCRIPTION: List the projects in the repository. To show hidden projects use the -all option
32  # OPTIONS: all, verbose
33  }
34 
35  \^H(ELP)?$ {
36  puts "$usage"
37  exit 0
38  # NAME: HELP or H
39  # DESCRIPTION: Display this help message or specific help for each directive
40  # OPTIONS:
41  }
42 
43  \^(CHECKCI|CIE)?$ {
44  set do_check_ci_env 1
45  # NAME: CHECKCIENV or CIE
46  # DESCRIPTION: Check that the common environment variables needed for Hog-CI are set
47  # OPTIONS: verbose
48  }
49 
50  \^(CHECKPROJENV|CPE)?$ {#
51  set do_checkproj_env 1
52  # NAME: CHECKPROJENV or CPE
53  # DESCRIPTION: Check that the environment variables needed for Hog-CI to run the chosen project are set and point to valid paths
54  # OPTIONS: verbose
55  }
56 
57  \^(CHECKPROJVER|CPV)?$ {#
58  set do_checkproj_ver 1
59  # NAME: CHECKPROJVER or CPV
60  # DESCRIPTION: Check the project version just before creating the HDL project in Create_Project stage. \
61  The CI job will SKIP the project pipeline, if it the project has not been modified with respect to the target branch.
62  # OPTIONS: ext_path.arg, simcheck, verbose
63  }
64 
65  \^C(REATE)?$ {#
66  set do_create 1
67  set recreate 1
68  # NAME*: CREATE or C
69  # DESCRIPTION: Create the project, replace it if already existing.
70  # OPTIONS: ext_path.arg, lib.arg, vivado_only, verbose
71  }
72 
73  \^I(MPL(EMENT(ATION)?)?)?$ {#
74  set do_implementation 1
75  set do_bitstream 1
76  set do_compile 1
77  # NAME: IMPLEMENTATION or I
78  # DESCRIPTION: Runs only the implementation, the project must already exist and be synthesised.
79  # OPTIONS: check_syntax, ext_path.arg, njobs.arg, no_bitstream, no_reset, recreate, verbose
80  }
81 
82  \^SYNT(H(ESIS(E)?)?)? {#
83  set do_synthesis 1
84  set do_compile 1
85  # NAME: SYNTH
86  # DESCRIPTION: Run synthesis only, create the project if not existing.
87  # OPTIONS: check_syntax, ext_path.arg, njobs.arg, recreate, verbose
88  }
89 
90  \^S(IM(ULAT(ION|E)?)?)?$ {#
91  set do_simulation 1
92  set do_create 1
93  # NAME*: SIMULATION or S
94  # DESCRIPTION: Simulate the project, creating it if not existing, unless it is a GHDL simulation.
95  # OPTIONS: check_syntax, compile_only, ext_path.arg, lib.arg, recreate, scripts_only, simset.arg, verbose
96  }
97 
98  \^W(ORK(FLOW)?)?$ {#
99  set do_implementation 1
100  set do_synthesis 1
101  set do_bitstream 1
102  set do_compile 1
103  set do_vitis_build 0
104  # NAME*: WORKFLOW or W
105  # DESCRIPTION: Runs the full workflow, creates the project if not existing.
106  # OPTIONS: bitstream_only, check_syntax, ext_path.arg, impl_only, njobs.arg, no_bitstream, recreate, synth_only, verbose, vitis_only, xsa.arg
107  }
108 
109  \^(CREATEWORKFLOW|CW)?$ {#
110  set do_implementation 1
111  set do_synthesis 1
112  set do_bitstream 1
113  set do_compile 1
114  set recreate 1
115  set do_vitis_build 0
116  # NAME: CREATEWORKFLOW or CW
117  # DESCRIPTION: Creates the project -even if existing- and launches the complete workflow.
118  # OPTIONS: check_syntax, ext_path.arg, njobs.arg, no_bitstream, synth_only, verbose, vivado_only, vitis_only, xsa.arg
119  }
120 
121  \^(CHECKSYNTAX|CS)?$ {#proj
122  set do_check_syntax 1
123  # NAME: CHECKSYNTAX or CS
124  # DESCRIPTION: Check the syntax of the project. Only for Vivado, Quartus and Libero projects.
125  # OPTIONS: ext_path.arg, recreate, verbose
126  }
127 
128  ^(IPB(US)?)|(X(ML)?)$ {#proj
129  set do_ipbus_xml 1
130  # NAME: IPBUS or IPB
131  # DESCRIPTION: Copy, check or create the IPbus XMLs for the project.
132  # OPTIONS: dst_dir.arg, generate, verbose
133  }
134 
135  \^V(IEW)?$ {#proj
136  set do_list_file_parse 1
137  # NAME*: VIEW or V
138  # DESCRIPTION: Print Hog list file contents in a tree-like fashon.
139  # OPTIONS: verbose
140  }
141 
142  \^(CHECKYAML|YML)?$ {
143  set min_n_of_args -1
144  set max_n_of_args 1
145  set do_check_yaml_ref 1
146  # NAME: CHECKYML or YML
147  # DESCRIPTION: Check that the ref to Hog repository in the .gitlab-ci.yml file, matches the one in Hog submodule.
148  # OPTIONS: verbose
149  }
150 
151  \^B(UTTONS)?$ {
152  set min_n_of_args -1
153  set max_n_of_args 1
154  set do_buttons 1
155  # NAME: BUTTONS or B
156  # DESCRIPTION: Add Hog buttons to the Vivado GUI, to check and recreate Hog list and configuration files.
157  # OPTIONS: verbose
158  }
159 
160  \^(CHECKLIST|CL)?$ {#proj
161  set do_check_list_files 1
162  # NAME: CHECKLIST or CL
163  # DESCRIPTION: Check that list and configuration files on disk match what is on the project.
164  # OPTIONS: ext_path.arg, verbose
165  }
166 
167  \^COMPSIM(LIB)?$ {
168  set do_compile_lib 1
169  set argument_is_no_project 1
170  # NAME: COMPSIMLIB or COMPSIM
171  # DESCRIPTION: Compiles the simulation library for the chosen simulator with Vivado.
172  # OPTIONS: dst_dir.arg, verbose
173  }
174 
175  \^RTL(ANALYSIS)?$ {#
176  set do_rtl 1
177  # NAME: RTL or RTLANALYSIS
178  # DESCRIPTION: Elaborate the RTL analysis report for the chosen project.
179  # OPTIONS: check_syntax, recreate, verbose
180  }
181 
182  \^SIG(ASI)?$ {#
183  set do_sigasi 1
184  # NAME: SIGASI or SIG
185  # DESCRIPTION: Create a .csv file to be used in Sigasi.
186  # OPTIONS: verbose
187  }
188 
189  \^T(REE)?$ {#
190  set do_hierarchy 1
191  # NAME: TREE or T
192  # DESCRIPTION: Print the design hierarchy for the chosen project.
193  # OPTIONS: compile_order, ext_path.arg, ignore.arg, include_gen_prods, include_ieee, light, output.arg, top.arg, verbose
194  }
195 
196  default {
197  if {$directive != ""} {
198  set NO_DIRECTIVE_FOUND 1
199  } else {
200  puts "$usage"
201  exit 0
202  }
203  }
204 }
205 
206 # Add this bit above!
207 # \^NEW_DIRECTIVE?$ {
208 # set do_new_directive 1
209 # }
210 
211 
212 #parsing command options
213 set parameters {
214  {no_bitstream "If set, the bitstream file will not be produced."}
215  {recreate "If set, the project will be re-created if it already exists."}
216  {no_reset "If set, runs (synthesis and implementation) won't be reset before launching them."}
217  {check_syntax "If set, the HDL syntax will be checked at the beginning of the workflow."}
218  {njobs.arg 4 "Number of jobs. Default: 4"}
219  {ext_path.arg "" "Sets the absolute path for the external libraries."}
220  {lib.arg "" "Simulation library path, compiled or to be compiled"}
221  {synth_only "If set, only the synthesis will be performed."}
222  {impl_only "If set, only the implementation will be performed. This assumes synthesis was already done."}
223  {scripts_only "If set, the simulation scripts will be generated, but the simulation will not be run."}
224  {compile_only "If set, the simulation libraries will be compiled, but not run."}
225  {bitstream_only "If set, only the bitstream will be produced. This assumes implementation was already done. For a Vivado-Vitis\
226  project this command can be used to generate the boot artifacts including the ELF file(s) without running the\
227  full Vivado workflow."}
228  {vivado_only "If set, and project is vivado-vitis, vitis project will not be created."}
229  {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."}
230  {xsa.arg "" "If set, and project is vivado-vitis, use this xsa for creating platforms without a defined hw."}
231  {simset.arg "" "Simulation sets, separated by commas, to be run."}
232  {all "List all projects, including test projects. Test projects have #test on the second line of hog.conf."}
233  {generate "For IPbus XMLs, it will re create the VHDL address decode files."}
234  {dst_dir.arg "" "For reports, IPbus XMLs, set the destination folder (default is in the ./bin folder)."}
235  {output.arg "" "For tree hierarchy mode, set the output file (default is console)."}
236  {top.arg "" "For tree hierarchy mode, set the top module (default is the top module defined in hog.conf)."}
237  {ignore.arg "" "For tree hierarchy mode, filter's the printed hierarchy to exclude modules that match the given string."}
238  {include_ieee "" "For tree hierarchy mode, include IEEE/STD libraries in the printed hierarchy. (Default 0)"}
239  {include_gen_prods "" "For tree hierarchy mode, include IP generated products in the printed hierarchy. (Default 0)"}
240  {compile_order "" "For tree hierarchy mode, prints compile order instead of hierarchy."}
241  {verbose "If set, launch the script in verbose mode"}
242  {light "For tree hierarchy mode, print a light version of the hierarchy (without file paths)."}
243  {simcheck "If set, checks also the version of the simulation files."}
244 }
245 
246 set tcl_path [file normalize "[file dirname [info script]]"]
247 source $tcl_path/hog.tcl
248 source $tcl_path/create_project.tcl
249 
250 # Quartus needs extra packages and treats the argv in a different way
251 if {[IsQuartus]} {
252  load_package report
253  set argv $quartus(args)
254 }
255 
256 # Msg Debug "s: $::argv0 a: $argv"
257 
258 ### CUSTOM COMMANDS ###
259 set commands_path [file normalize "$tcl_path/../../hog-commands/"]
260 set custom_commands [GetCustomCommands $parameters $commands_path ]
261 
262 lassign [InitLauncher $::argv0 $tcl_path $parameters $default_commands $argv $custom_commands] \
263 directive project project_name group_name repo_path old_path bin_dir top_path usage short_usage cmd ide list_of_options
264 
265 array set options $list_of_options
266 
267 if {$options(verbose) == 1} {
268  setDebugMode 1
269 }
270 Msg Debug "Returned by InitLauncher: \n\
271  - project: $project \n\
272  - project_name $project_name \n\
273  - group_name $group_name \n\
274  - repo_path $repo_path \n\
275  - old_path $old_path \n\
276  - bin_dir $bin_dir \n\
277  - top_path $top_path \n\
278  - cmd $cmd"
279 
280 set ext_path ""
281 if {$options(ext_path) != ""} {
282  set ext_path $options(ext_path)
283 }
284 set simlib_path ""
285 
286 
287 
288 # printDebugMode
289 # Msg Info "Number of jobs set to $options(njobs)."
290 set output_path ""
291 if {$options(output) != ""} {
292  set output_path $options(output)
293 }
294 
295 set light_hierarchy $options(light)
296 set ignored_hierarchy $options(ignore)
297 set top_module $options(top)
298 set compile_order $options(compile_order)
299 set include_ieee $options(include_ieee)
300 set include_gen_prods $options(include_gen_prods)
301 
302 ######## DEFAULTS #########
303 set do_rtl 0
304 set do_checkproj_env 0; set do_check_ci_env 0; set do_checkproj_ver 0;
305 set do_implementation 0; set do_synthesis 0; set do_bitstream 0
306 set do_create 0; set do_compile 0; set do_simulation 0; set recreate 0
307 set do_reset 1; set do_list_all 2; set do_check_syntax 0; set do_vitis_build 0;
308 set scripts_only 0; set compile_only 0
309 ### Hog stand-alone directives ###
310 # The following directives are used WITHOUT ever calling the IDE, they are run in tclsh
311 # A place holder called new_directive can be followed to add new commands
312 
313 set do_ipbus_xml 0
314 set do_list_file_parse 0
315 set do_check_yaml_ref 0
316 set do_buttons 0
317 set do_check_list_files 0
318 set do_compile_lib 0
319 set do_sigasi 0
320 set do_hierarchy 0
321 
322 set NO_DIRECTIVE_FOUND 0
323 Msg Debug "Looking for a $directive in : $default_commands"
324 switch -regexp -- $directive $default_commands
325 
326 if {$NO_DIRECTIVE_FOUND == 1} {
327  Msg Debug "No directive found in default commands, looking in custom commands..."
328  if {[string length $custom_commands] > 0 && [dict exists $custom_commands $directive]} {
329  Msg Debug "Directive $directive found in custom commands."
330  if {$cmd == "custom_tcl"} {
331  eval [dict get $custom_commands $directive SCRIPT]
332  exit
333  } else {
334  if {[IsTclsh]} {
335  Msg Info "Launching command: $cmd..."
336 
337  # Check if the IDE is actually in the path...
338  set ret [catch {exec which $ide}]
339  if {$ret != 0} {
340  Msg Error "$ide not found in your system. Make sure to add $ide to your PATH enviromental variable."
341  exit $ret
342  }
343 
344  if {[string first libero $cmd] >= 0} {
345  # The SCRIPT_ARGS: flag of libero makes tcl crazy...
346  # Let's pipe the command into a shell script and remove it later
347  set libero_script [open "launch-libero-hog.sh" w]
348  puts $libero_script "#!/bin/sh"
349  puts $libero_script $cmd
350  close $libero_script
351  set cmd "sh launch-libero-hog.sh"
352  }
353 
354  set ret [catch {exec -ignorestderr {*}$cmd >@ stdout} result]
355 
356  if {$ret != 0} {
357  Msg Error "IDE returned an error state."
358  } else {
359  Msg Info "All done."
360  exit 0
361  }
362 
363  if {[string first libero $cmd] >= 0} {
364  file delete "launch-libero-hog.sh"
365  }
366 
367  exit $ret
368  }
369 
370  eval [dict get $custom_commands $directive SCRIPT]
371 
372  set no_exit [dict get $custom_commands $directive NO_EXIT]
373  if {$no_exit == 0} {
374  exit
375  }
376  }
377  } else {
378  Msg Info "No directive found, pre ide exiting..."
379  Msg Status "ERROR: Unknown directive $directive.\n\n"
380  puts $usage
381  exit
382  }
383 }
384 
385 if {$options(all) == 1} {
386  set do_list_all 1
387 } else {
388  set do_list_all 2
389 }
390 
391 if {$options(dst_dir) == "" && ($do_ipbus_xml == 1 || $do_check_list_files == 1) && $project != ""} {
392  # Getting all the versions and SHAs of the repository
393  lassign [GetRepoVersions [file normalize $repo_path/Top/$group_name/$project] \
394  $repo_path $ext_path] commit version hog_hash hog_ver top_hash top_ver libs hashes vers \
395  cons_ver cons_hash ext_names ext_hashes xml_hash xml_ver user_ip_repos \
396  user_ip_hashes user_ip_vers
397  cd $repo_path
398 
399  set describe [GetHogDescribe $commit $repo_path]
400  set dst_dir [file normalize "$repo_path/bin/$group_name/$project\-$describe"]
401 }
402 
403 if {$cmd == -1} {
404  #This is if the project was not found
405  Msg Status "\n\nPossible projects are:"
406  ListProjects $repo_path $do_list_all
407  Msg Status "\n"
408  exit 1
409 } elseif {$cmd == -2} {
410  # Project not given but needed
411  Msg Status "ERROR: You must specify a project with directive $directive."
412  # \n\n[cmdline::usage $parameters $usage]"
413  Msg Status "Possible projects are:"
414  ListProjects $repo_path $do_list_all
415  exit 1
416 } elseif {$cmd == 0} {
417  #This script was launched within the IDE,: Vivado, Quartus, etc
418  Msg Info "$::argv0 was launched from the IDE."
419 } else {
420  # This script was launched with Tclsh, we need to check the arguments
421  # and if everything is right launch the IDE on this script and return
422  #### Directives to be handled in tclsh should be here ###
423  ### IMPORTANT: Each if block should either end with "exit 0" or
424  ### set both $ide and $cmd to be executed when this script is run again
425  if {$do_checkproj_env == 1} {
426  CheckEnv $project_name $ide
427  exit 0
428  }
429 
430  if {$do_check_ci_env == 1} {
431  CheckCIEnv
432  exit 0
433  }
434 
435 
436  if {$do_ipbus_xml == 1} {
437  Msg Info "Handling IPbus XMLs for $project_name..."
438 
439  set proj_dir $repo_path/Top/$project_name
440 
441  if {$options(generate) == 1} {
442  set xml_gen 1
443  } else {
444  set xml_gen 0
445  }
446 
447  if {$options(dst_dir) != ""} {
448  set dst_dir $options(dst_dir)
449  }
450  set xml_dst "$dst_dir/xml"
451 
452 
453  if {[llength [glob -nocomplain $proj_dir/list/*.ipb]] > 0} {
454  if {![file exists $xml_dst]} {
455  Msg Info "$xml_dst directory not found, creating it..."
456  file mkdir $xml_dst
457  }
458  } else {
459  Msg Error "No .ipb files found in $proj_dir/list/"
460  exit
461  }
462 
463  set ret [GetRepoVersions $proj_dir $repo_path ""]
464  set sha [lindex $ret 13]
465  set hex_ver [lindex $ret 14]
466 
467  set ver [HexVersionToString $hex_ver]
468  CopyIPbusXMLs $proj_dir $repo_path $xml_dst $ver $sha 1 $xml_gen
469 
470  exit 0
471  }
472 
473  if {$do_list_file_parse == 1} {
474  set proj_dir $repo_path/Top/$project_name
475  set proj_list_dir $repo_path/Top/$project_name/list
476  GetHogFiles -print_log -list_files {.src,.con,.sim,.ext,.ipb} $proj_list_dir $repo_path
477  Msg Status " "
478  Msg Info "All Done."
479  exit 0
480  }
481 
482  if {$do_hierarchy == 1} {
483  source $tcl_path/utils/hierarchy.tcl
484  set proj_dir $repo_path/Top/$project_name
485  set proj_list_dir $repo_path/Top/$project_name/list
486  lassign [GetHogFiles -ext_path $ext_path \
487  -list_files ".src,.ext" $proj_list_dir $repo_path]\
488  listLibraries listProperties listSrcSets
489  Hierarchy $listProperties $listLibraries $repo_path $output_path $compile_order \
490  $light_hierarchy $top_module $ignored_hierarchy $include_ieee $include_gen_prods
491  exit 0
492  }
493  if {$do_sigasi == 1} {
494  cd $repo_path
495  Msg Info "Creating Sigasi CSV files for project $project_name..."
496  set proj_dir $repo_path/Top/$project_name
497  set proj_list_dir $repo_path/Top/$project_name/list
498  set project [file tail $project_name]
499  lassign [GetHogFiles -list_files {.src} $proj_list_dir $repo_path] libraries
500  set csv_file [open "sigasi_$project.csv" w]
501  foreach lib $libraries {
502  set source_files [DictGet $libraries $lib]
503  foreach source_file $source_files {
504  if {[file extension $source_file] == ".vhd" ||
505  [file extension $source_file] == ".vhdl" ||
506  [file extension $source_file] == ".sv" ||
507  [file extension $source_file] == ".v" } {
508  puts $csv_file [ concat [file rootname $lib] "," $source_file ]
509  }
510  }
511  }
512  close $csv_file
513  Msg Info "Sigasi CSV file created: sigasi_$project.csv"
514  Msg Info "You can use the python script provided by Sigasi to convert the generated csv file into a Sigasi project."
515  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"
516  exit 0
517  }
518 
519  if {$do_check_yaml_ref == 1} {
520  Msg Info "Checking if \"ref\" in .gitlab-ci.yml actually matches the included yml file in Hog submodule"
521  CheckYmlRef $repo_path false
522  exit 0
523  }
524 
525  if {$do_buttons == 1} {
526  Msg Info "Adding Hog buttons to Vivado bar (will use the vivado currently in PATH)..."
527  set ide vivado
528  set cmd "vivado -mode batch -notrace -source $repo_path/Hog/Tcl/utils/add_hog_custom_button.tcl"
529  }
530 
531  if {$do_compile_lib == 1} {
532  if {$project eq ""} {
533  Msg Error "You need to specify a simulator as first argument."
534  exit 1
535  } else {
536  set simulator $project
537  Msg Info "Selecting $simulator simulator..."
538  }
539  if {$options(dst_dir) != ""} {
540  set output_dir $options(dst_dir)
541  } else {
542  Msg Info "No destination directory defined. Using default: SimulationLib/"
543  set output_dir "SimulationLib"
544  }
545 
546  set ide vivado
547  set cmd "vivado -mode batch -notrace -source $repo_path/Hog/Tcl/utils/compile_simlib.tcl -tclargs -simulator $simulator -output_dir $output_dir"
548  }
549 
550  set simsets ""
551  if {$do_simulation == 1} {
552  # Get all simsets in the project that run with GHDL
553  set ghdl_simsets [GetSimSets $project_name $repo_path "$options(simset)" 1]
554  set ghdl_import 0
555  dict for {simset_name simset_dict} $ghdl_simsets {
556  if {$ghdl_import == 0} {
557  ImportGHDL $project_name $repo_path $simset_name $simset_dict $ext_path
558  set ghdl_import 1
559  }
560  LaunchGHDL $project_name $repo_path $simset_name $simset_dict $ext_path
561  # dict unset simsets_dict $simset_name
562  }
563  set ide_simsets [GetSimSets $project_name $repo_path $options(simset) 0 1]
564 
565  if {[dict size $ide_simsets] == 0} {
566  # All simulations have been run, exiting
567  Msg Info "All simulations have been run, exiting..."
568  exit 0
569  }
570  }
571 
572  # if {$do_new_directive ==1 } {
573  #
574  # # Do things here
575  #
576  # exit 0
577  #}
578 
579  #### END of tclsh commands ####
580  Msg Info "Launching command: $cmd..."
581 
582  # Check if the IDE is actually in the path...
583  set ret [catch {exec which $ide}]
584  if {$ret != 0} {
585  Msg Error "$ide not found in your system. Make sure to add $ide to your PATH enviromental variable."
586  exit $ret
587  }
588 
589  if {[string first libero $cmd] >= 0} {
590  # The SCRIPT_ARGS: flag of libero makes tcl crazy...
591  # Let's pipe the command into a shell script and remove it later
592  set libero_script [open "launch-libero-hog.sh" w]
593  puts $libero_script "#!/bin/sh"
594  puts $libero_script $cmd
595  close $libero_script
596  set cmd "sh launch-libero-hog.sh"
597  }
598 
599  set ret [catch {exec -ignorestderr {*}$cmd >@ stdout} result]
600 
601  if {$ret != 0} {
602  Msg Error "IDE returned an error state."
603  } else {
604  Msg Info "All done."
605  exit 0
606  }
607 
608  if {[string first libero $cmd] >= 0} {
609  file delete "launch-libero-hog.sh"
610  }
611 
612  exit $ret
613 }
614 
615 #After this line, we are in the IDE
616 ##################################################################################
617 
618 
619 # We need to Import tcllib if we are using Libero
620 if {[IsLibero] || [IsDiamond]} {
621  if {[info exists env(HOG_TCLLIB_PATH)]} {
622  lappend auto_path $env(HOG_TCLLIB_PATH)
623  } else {
624  puts "ERROR: To run Hog with Microsemi Libero SoC or Lattice Diamond,\
625  you need to define the HOG_TCLLIB_PATH variable."
626  return
627  }
628 }
629 
630 if {[catch {package require cmdline} ERROR] || [catch {package require struct::matrix} ERROR]} {
631  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'"
632  exit 1
633 }
634 
635 ## CHECK PROJECT VERSION
636 if {$do_checkproj_ver == 1} {
637  CheckProjVer $repo_path $project_name $options(simcheck) $options(ext_path)
638  exit 0
639 }
640 
641 set run_folder [file normalize "$repo_path/Projects/$project_name/$project.runs/"]
642 if {[IsLibero]} {
643  set run_folder [file normalize "$repo_path/Projects/$project_name/"]
644 }
645 
646 # Only for quartus, not used otherwise
647 set project_path [file normalize "$repo_path/Projects/$project_name/"]
648 
649 # Get IDE name from project config file
650 set proj_conf [ProjectExists $project_name $repo_path]
651 set ide_name_and_ver [string tolower [GetIDEFromConf $proj_conf]]
652 set ide_name [lindex [regexp -all -inline {\S+} $ide_name_and_ver] 0]
653 
654 if {$options(no_bitstream) == 1} {
655  set do_bitstream 0
656  set do_compile 0
657 }
658 
659 if {$options(recreate) == 1} {
660  set recreate 1
661 }
662 
663 if {$options(synth_only) == 1} {
664  set do_implementation 0
665  set do_synthesis 1
666  set do_bitstream 0
667  set do_create 1
668  set do_compile 1
669 }
670 
671 if {$options(impl_only) == 1} {
672  set do_implementation 1
673  set do_synthesis 0
674  set do_bitstream 0
675  set do_create 0
676  set do_compile 1
677 }
678 
679 if {$options(vitis_only) == 1 || $ide_name eq "vitis_classic"} {
680  set do_vitis_build 1
681  set do_implementation 0
682  set do_synthesis 0
683  set do_bitstream 0
684  set do_create 0
685  set do_compile 0
686 }
687 
688 if {$options(bitstream_only) == 1} {
689  set do_bitstream_only 1
690  set do_bitstream 0
691  set do_implementation 0
692  set do_synthesis 0
693  set do_create 0
694  set do_compile 0
695 } else {
696  set do_bitstream_only 0
697 }
698 
699 if {$options(vivado_only) == 1} {
700  set do_vitis_build 0
701 }
702 
703 if {$options(no_reset) == 1} {
704  set do_reset 0
705 }
706 
707 if {$options(check_syntax) == 1} {
708  set do_check_syntax 1
709 }
710 
711 if {$options(scripts_only) == 1} {
712  set scripts_only 1
713 }
714 
715 if {$options(compile_only) == 1} {
716  set compile_only 1
717 }
718 
719 
720 
721 if {$options(lib) != ""} {
722  set lib_path [file normalize $options(lib)]
723 } else {
724  if {[info exists env(HOG_SIMULATION_LIB_PATH)]} {
725  set lib_path $env(HOG_SIMULATION_LIB_PATH)
726  } else {
727  if {[file exists "$repo_path/SimulationLib"]} {
728  set lib_path [file normalize "$repo_path/SimulationLib"]
729  } else {
730  set lib_path ""
731  }
732  }
733 }
734 
735 
736 Msg Info "Number of jobs set to $options(njobs)."
737 
738 ############## Quartus ########################
739 set argv ""
740 
741 ############# CREATE or OPEN project ############
742 if {[IsISE]} {
743  cd $tcl_path
744  set project_file [file normalize $repo_path/Projects/$project_name/$project.ppr]
745 } elseif {[IsVivado]} {
746  cd $tcl_path
747  set project_file [file normalize $repo_path/Projects/$project_name/$project.xpr]
748 } elseif {[IsVitisClassic]} {
749  cd $tcl_path
750  set project_file [file normalize $repo_path/Projects/$project_name/vitis_classic/.metadata/]
751  Msg Info "Setting project file for Vitis Classic project $project_name to $project_file"
752 } elseif {[IsQuartus]} {
753  if {[catch {package require ::quartus::project} ERROR]} {
754  Msg Error "$ERROR\n Can not find package ::quartus::project"
755  cd $old_path
756  return 1
757  } else {
758  Msg Info "Loaded package ::quartus::project"
759  load_package flow
760  }
761  set project_file "$project_path/$project.qpf"
762 } elseif {[IsLibero]} {
763  set project_file [file normalize $repo_path/Projects/$project_name/$project.prjx]
764 } elseif {[IsDiamond]} {
765  sys_install version
766  set project_file [file normalize $repo_path/Projects/$project_name/$project.ldf]
767 }
768 
769 if {[file exists $project_file]} {
770  Msg Info "Found project file $project_file for $project_name."
771  set proj_found 1
772 } else {
773  Msg Info "Project file not found for $project_name."
774  set proj_found 0
775 }
776 
777 if {($proj_found == 0 || $recreate == 1)} {
778  Msg Info "Creating (possibly replacing) the project $project_name..."
779  Msg Debug "launch.tcl: calling GetConfFiles with $repo_path/Top/$project_name"
780  lassign [GetConfFiles $repo_path/Top/$project_name] conf sim pre post
781 
782  if {[file exists $conf]} {
783  # Still not sure of the difference between project and project_name
784  if {$options(vivado_only) == 1} {
785  CreateProject -simlib_path $lib_path -xsa $options(xsa) -vivado_only $project_name $repo_path
786  } else {
787  CreateProject -simlib_path $lib_path -xsa $options(xsa) $project_name $repo_path
788  }
789  Msg Info "Done creating project $project_name."
790  } else {
791  Msg Error "Project $project_name is incomplete: no hog.conf file found, please create one..."
792  }
793 } else {
794  Msg Info "Opening existing project file $project_file..."
795  if {[IsXilinx]} {
796  file mkdir "$repo_path/Projects/$project_name/$project.gen/sources_1"
797  }
798 
799  if {[IsVitisClassic]} {
800  set vitis_workspace [file normalize $repo_path/Projects/$project_name/vitis_classic/]
801  Msg Info "Setting workspace to $vitis_workspace"
802  setws $vitis_workspace
803 
804  } else {
805  OpenProject $project_file $repo_path
806  }
807 }
808 
809 ########## CHECK SYNTAX ###########
810 if {$do_check_syntax == 1} {
811  Msg Info "Checking syntax for project $project_name..."
812  CheckSyntax $project_name $repo_path $project_file
813 }
814 
815 ######### RTL ANALYSIS ########
816 if {$do_rtl == 1} {
817  LaunchRTLAnalysis $repo_path
818 }
819 
820 if {$do_vitis_build == 1} {
821  if {[IsVitisClassic]} {
822  LaunchVitisBuild $project_name $repo_path
823  } else {
824  set xsct_cmd "xsct $tcl_path/launch.tcl W -vitis_only $project_name"
825  set ret [catch {exec -ignorestderr {*}$xsct_cmd >@ stdout} result]
826  if {$ret != 0} {
827  Msg Error "xsct (vitis classic) returned an error state."
828  }
829  }
830 }
831 
832 ######### LaunchSynthesis ########
833 if {$do_synthesis == 1} {
834  LaunchSynthesis $do_reset $do_create $run_folder $project_name $repo_path $ext_path $options(njobs)
835 }
836 
837 if {$do_implementation == 1} {
838  LaunchImplementation $do_reset $do_create $run_folder $project_name $repo_path $options(njobs) $do_bitstream
839 }
840 
841 if {$do_bitstream_only == 1 && [IsXilinx]} {
842  GenerateBitstreamOnly $project_name $repo_path
843 } elseif {$do_bitstream_only == 1 && ![IsXilinx]} {
844  Msg Error "Bitstream only option is not supported for this IDE."
845 }
846 
847 if {$do_bitstream == 1 && ![IsXilinx]} {
848  GenerateBitstream $run_folder $repo_path $options(njobs)
849 }
850 
851 if {$do_simulation == 1} {
852  # set simsets $options(simset)
853  set simsets [GetSimSets $project_name $repo_path $options(simset)]
854  LaunchSimulation $project_name $lib_path $simsets $repo_path $scripts_only $compile_only
855 }
856 
857 
858 if {$do_check_list_files} {
859  Msg Info "Running list file checker..."
860 
861  #if {![file exists $dst_dir]} {
862  # Msg Info "$dst_dir directory not found, creating it..."
863  # file mkdir $dst_dir
864  # }
865 
866 
867  set argv0 check_list_files
868  if {$ext_path ne ""} {
869  set argv [list "-ext_path" "$ext_path" "-outDir" "$dst_dir" "-pedantic"]
870  } else {
871  set argv [list "-outDir" "$dst_dir" "-pedantic"]
872  }
873 
874  source $tcl_path/utils/check_list_files.tcl
875 }
876 ## CLOSE Project
878 
879 Msg Info "All done."
880 cd $old_path