Hog Hog2026.2-1
post-bitstream.tcl
Go to the documentation of this file.
1 #!/usr/bin/env tclsh
2 # Copyright 2018-2026 The University of Birmingham
3 # Copyright 2018-2026 Max-Planck-Institute for Physics
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 # @file
18 # The post bitstream script copies binary files, reports and other files to the bin directory in your repository.
19 # This script is automatically integrated into the Vivado/Quartus workflow by the Create Project script.
20 
21 set old_path [pwd]
22 set tcl_path [file normalize "[file dirname [info script]]/.."]
23 source $tcl_path/hog.tcl
24 set repo_path [file normalize "$tcl_path/../../"]
25 
26 
27 # write_hw_platform has weird behavior when run in post-bitstream hook;
28 # workaround by launching a separate Vivado instance to run it
29 proc WriteHwPlatformWorkaround {hw_platform_args} {
30  global proj_dir proj_name work_path
31  set proj_file [file normalize "$proj_dir/$proj_name.xpr"]
32  set impl_run [file tail $work_path]
33  set tmp_script "$work_path/hog_write_hw_platform_tmp.tcl"
34 
35  set fp [open $tmp_script w]
36  puts $fp "open_project {$proj_file}"
37  puts $fp "open_run $impl_run"
38  puts $fp "write_hw_platform $hw_platform_args"
39  puts $fp "close_project"
40  close $fp
41 
42  Msg Info "Launching another Vivado instance to run write_hw_platform for $impl_run..."
43  set ret [catch {exec vivado -mode batch -notrace -source $tmp_script >@ stdout 2>@ stderr} result]
44 
45  if {$ret != 0} {
46  Msg Error "write_hw_platform failed in separate Vivado instance:\n$result"
47  } else {
48  Msg Info "write_hw_platform completed successfully in separate Vivado instance for $impl_run."
49  }
50  return $ret
51 }
52 
53 # Import tcllib
54 if {[IsLibero] || [IsDiamond]} {
55  if {[info exists env(HOG_TCLLIB_PATH)]} {
56  lappend auto_path $env(HOG_TCLLIB_PATH)
57  } else {
58  puts "ERROR: To run Hog with Microsemi Libero SoC, you need to define the HOG_TCLLIB_PATH variable."
59  return
60  }
61 }
62 
63 if {[info exists env(HOG_EXTERNAL_PATH)]} {
64  set ext_path $env(HOG_EXTERNAL_PATH)
65  Msg Info "Found environment variable HOG_EXTERNAL_PATH, setting path for external files to $ext_path..."
66 } else {
67  set ext_path ""
68 }
69 
70 set bin_dir [file normalize "$repo_path/bin"]
71 
72 if {[IsXilinx]} {
73  # Binary files are called .bit for ISE and for Vivado unless the chip is a Versal
74  set fw_file_ext "bit"
75 
76  # Vivado + PlanAhead
77  if {[IsISE]} {
78  # planAhead
79  set work_path [get_property DIRECTORY [get_runs impl_1]]
80  } else {
81  # Vivado
82  set work_path $old_path
83  if {[IsVersal [get_property PART [current_design]]]} {
84  #In Vivado if a Versal chip is used, the main binary file is called .pdi
85  set fw_file_ext "pdi"
86  }
87  }
88 
89  set main_files [lsort [glob -nocomplain "$work_path/*.$fw_file_ext"]]
90  if {[llength $main_files] > 1} {
91  #In case of segmented configuration on Versal there are 2 .pdi files: <top>_boot.pdi and <top>_pld.pdi
92  # Main file is the pld, so not the first
93  set main_file [file normalize [lindex $main_files 1]]
94  # Secondary file is the boot, so the first!
95  set secondary_file [file normalize [lindex $main_files 0]]
96  set main_file_suffix "_pld"
97  set secondary_file_suffix "_boot"
98  Msg Info "Found main and secondary binary file main: [file tail $main_file], secondary: [file tail $secondary_file]..."
99  # remove _pld suffix only at the end
100  set top_name [regsub $main_file_suffix\$ [file rootname [file tail $main_file]] ""]
101  if {[llength $main_files] > 2} {
102  Msg Warning "Multiple (more than 2) binary files found: $main_files."
103  }
104  } else {
105  set main_file [file normalize [lindex $main_files 0]]
106  set main_file_suffix ""
107  set secondary_file ""
108  set secondary_file_suffix ""
109  set top_name [file rootname [file tail $main_file]]
110  }
111 
112 
113  set proj_name [file tail [file normalize $work_path/../../]]
114  set proj_dir [file normalize "$work_path/../.."]
115 
116 
117  set additional_ext ".bin .ltx .bif .mmi"
118 
119  set xml_dir [file normalize "$work_path/../xml"]
120  set run_dir [file normalize "$work_path/.."]
121 } elseif {[IsQuartus]} {
122  # Quartus
123  ##nagelfar ignore Unknown variable
124  set proj_name [lindex $quartus(args) 1]
125  set proj_dir [pwd]
126  set xml_dir [file normalize "$repo_path/xml"]
127  set run_dir [file normalize "$proj_dir"]
128  set name [file rootname [file tail [file normalize [pwd]]]]
129  # programming object file
130  set pof_file [file normalize "$proj_dir/output_files/$proj_name.pof"]
131  # SRAM Object File
132  set sof_file [file normalize "$proj_dir/output_files/$proj_name.sof"]
133  # raw binary file
134  set rbf_file [file normalize "$proj_dir/output_files/$proj_name.rbf"]
135  #raw programming file
136  set rpd_file [file normalize "$proj_dir/output_files/$proj_name.rpd"]
137  # signal tap file
138  set stp_file [file normalize "$proj_dir/output_files/$proj_name.stp"]
139  #source and probes file
140  set spf_file [file normalize "$proj_dir/output_files/$proj_name.spf"]
141 } elseif {[IsLibero]} {
142  # Libero
143  ##nagelfar ignore Unknown variable
144  set proj_name $project
145  ##nagelfar ignore Unknown variable
146  set proj_dir $main_folder
147  set map_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.map"] 0]]
148  set sap_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.sap"] 0]]
149  set srd_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.srd"] 0]]
150  set srm_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.srm"] 0]]
151  set srs_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.srs"] 0]]
152  set srr_file [file normalize [lindex [glob -nocomplain "$proj_dir/synthesis/*.srr"] 0]]
153  set top_name [file rootname [file tail $srr_file]]
154  set stxt_files [glob -nocomplain "$proj_dir/synthesis/*.txt"]
155  set scsv_files [glob -nocomplain "$proj_dir/synthesis/*.csv"]
156  set slog_files [glob -nocomplain "$proj_dir/synthesis/*.log"]
157  set srpt_files [glob -nocomplain "$proj_dir/synthesis/*.rpt"]
158  set dtxt_files [glob -nocomplain "$proj_dir/designer/$top_name/*.txt"]
159  set dcsv_files [glob -nocomplain "$proj_dir/designer/$top_name/*.csv"]
160  set dlog_files [glob -nocomplain "$proj_dir/designer/$top_name/*.log"]
161  set drpt_files [glob -nocomplain "$proj_dir/designer/$top_name/*.rpt"]
162  set xml_dir [file normalize "$repo_path/xml"]
163 } elseif {[IsDiamond]} {
164  set proj_dir [file normalize "[pwd]/.."]
165  set proj_name [file tail $proj_dir]
166  set project $proj_name
167  set xml_dir [file normalize "$repo_path/xml"]
168  set main_file [file normalize "$proj_dir/Implementation0/${proj_name}_Implementation0"]
169 } else {
170  #tcl shell
171  set work_path $old_path
172  set fw_file [file normalize [lindex [glob -nocomplain "$work_path/*.bit"] 0]]
173  set proj_name [file tail [file normalize $work_path/../../]]
174  set proj_dir [file normalize "$work_path/../.."]
175 
176  set top_name [file rootname [file tail $fw_file]]
177 
178  set main_file [file normalize "$work_path/$top_name.bit"]
179  set bin_file [file normalize "$work_path/$top_name.bin"]
180  set ltx_file [file normalize "$work_path/$top_name.ltx"]
181 
182  set xml_dir [file normalize "$work_path/../xml"]
183  set run_dir [file normalize "$work_path/.."]
184 }
185 
186 set group_name [GetGroupName $proj_dir "$tcl_path/../.."]
187 # Go to repository path
188 cd $repo_path
189 
190 Msg Info "Evaluating Hog describe for $proj_name..."
191 set describe [GetHogDescribe [file normalize ./Top/$group_name/$proj_name] $repo_path]
192 Msg Info "Hog describe set to: $describe"
193 
194 set dst_dir [file normalize "$bin_dir/$group_name/$proj_name\-$describe"]
195 set dst_xml [file normalize "$dst_dir/xml"]
196 
197 Msg Info "Creating $dst_dir..."
198 file mkdir $dst_dir
199 
200 set ts [clock format [clock seconds] -format {%Y-%m-%d-%H-%M}]
201 
202 
203 # Vivado
204 if {[IsXilinx] && [file exists $main_file]} {
205  set dst_main [file normalize "$dst_dir/$proj_name$main_file_suffix\-$describe.$fw_file_ext"]
206  Msg Info "Copying main binary file $main_file into $dst_main..."
207  file copy -force $main_file $dst_main
208  if {$secondary_file != ""} {
209  set dst_secondary [file normalize "$dst_dir/$proj_name$secondary_file_suffix\-$describe.$fw_file_ext"]
210  Msg Info "Copying secondary binary file $secondary_file into $dst_secondary..."
211  file copy -force $secondary_file $dst_secondary
212  }
213 
214 
215  # Additional files
216  # In case of Segmented Configuration, there are 2 files per extension.
217 
218  set ltx_files {}
219  lappend ltx_files "$top_name.ltx"
220 
221  if {$main_file_suffix != ""} {
222  foreach e $additional_ext {
223  lappend new_ext $e
224  lappend new_ext $main_file_suffix$e
225  lappend new_ext $secondary_file_suffix$e
226  lappend ltx_files "$top_name$main_file_suffix.ltx"
227  lappend ltx_files "$top_name$secondary_file_suffix.ltx"
228  }
229  set additional_ext $new_ext
230  }
231 
232 
233  # LTX file for ILA, needs a special treatment...
234  foreach l $ltx_files {
235  set ltx_file "$work_path/$l"
236  Msg Info "Writing debug probes for $ltx_file..."
237  write_debug_probes -quiet $ltx_file
238  }
239 
240  foreach e $additional_ext {
241  set orig [file normalize "$work_path/$top_name$e"]
242  set dst [file normalize "$dst_dir/$proj_name\-$describe$e"]
243  if {[file exists $work_path/$top_name$e] == 1} {
244  Msg Info "Copying $orig file into $dst..."
245  file copy -force $orig $dst
246  } else {
247  Msg Debug "File: $orig not found."
248  }
249  }
250 } elseif {[IsQuartus]} {
251  set dst_pof [file normalize "$dst_dir/$name\-$describe.pof"]
252  set dst_sof [file normalize "$dst_dir/$name\-$describe.sof"]
253  set dst_rbf [file normalize "$dst_dir/$name\-$describe.rbf"]
254  set dst_rpd [file normalize "$dst_dir/$name\-$describe.rpd"]
255  set dst_stp [file normalize "$dst_dir/$name\-$describe.stp"]
256  set dst_spf [file normalize "$dst_dir/$name\-$describe.spf"]
257  set dst_xml [file normalize "$dst_dir/xml"]
258 
259  Msg Info "Evaluating differences with last commit..."
260  set found_uncommitted 0
261  set diff [Git diff]
262  if {$diff != ""} {
263  set found_uncommitted 1
264  Msg Warning "Found non committed changes:"
265  Msg Status "$diff"
266  set fp [open "$dst_dir/diff_postbistream.txt" w+]
267  puts $fp "$diff"
268  close $fp
269  }
270 
271  if {$found_uncommitted == 0} {
272  Msg Info "No uncommitted changes found."
273  }
274 
275  #pof file
276  if {[file exists $pof_file]} {
277  Msg Info "Copying pof file $pof_file into $dst_pof..."
278  file copy -force $pof_file $dst_pof
279  } else {
280  Msg Info "No pof file found: $pof_file, that is not a problem"
281  }
282 
283  #Reports
284  file mkdir $dst_dir/reports
285  set reps [glob -nocomplain "$proj_dir/output_files/*.rpt"]
286 
287  if {[file exists [lindex $reps 0]]} {
288  file copy -force {*}$reps $dst_dir/reports
289  } else {
290  Msg Warning "No reports found in $proj_dir/output_files subfolders"
291  }
292 
293  # sof File
294  if {[file exists $sof_file]} {
295  Msg Info "Copying sof file $sof_file into $dst_sof..."
296  file copy -force $sof_file $dst_sof
297  } else {
298  Msg Info "No sof file found: $sof_file, that is not a problem"
299  }
300 
301 
302  #rbf rpd
303  if {[file exists $rbf_file] || [file exists $rpd_file]} {
304  if {[file exists $rbf_file]} {
305  file copy -force $rbf_file $dst_rbf
306  }
307  if {[file exists $rpd_file]} {
308  file copy -force $rpd_file $dst_rpd
309  }
310  } else {
311  Msg Info "No rbf or rpd file found: this is not a problem"
312  }
313 
314  # stp and spf File
315  if {[file exists $stp_file] || [file exists $spf_file]} {
316  if {[file exists $stp_file]} {
317  file copy -force $stp_file $dst_stp
318  }
319  if {[file exists $spf_file]} {
320  file copy -force $spf_file $dst_spf
321  }
322  } else {
323  Msg Info "No stp or spf file found: that is not a problem"
324  }
325 } elseif {[IsLibero]} {
326  set dst_map [file normalize "$dst_dir/$project\-$describe.map"]
327  set dst_sap [file normalize "$dst_dir/$project\-$describe.sap"]
328  set dst_srd [file normalize "$dst_dir/$project\-$describe.srd"]
329  set dst_srm [file normalize "$dst_dir/$project\-$describe.srm"]
330  set dst_srs [file normalize "$dst_dir/$project\-$describe.srs"]
331  set dst_srr [file normalize "$dst_dir/$project\-$describe.srr"]
332  set dst_rpt [file normalize "$dst_dir/reports"]
333  set dst_xml [file normalize "$dst_dir/xml"]
334 
335  file mkdir $dst_dir/reports
336 
337  if {[file exists $map_file]} {
338  Msg Info "Copying map file $map_file into $dst_map..."
339  file copy -force $map_file $dst_map
340  }
341 
342  if {[file exists $sap_file]} {
343  Msg Info "Copying sap file $sap_file into $dst_sap..."
344  file copy -force $sap_file $dst_sap
345  }
346 
347  if {[file exists $srd_file]} {
348  Msg Info "Copying srd file $srd_file into $dst_srd..."
349  file copy -force $srd_file $dst_srd
350  }
351 
352  if {[file exists $srm_file]} {
353  Msg Info "Copying srm file $srm_file into $dst_srm..."
354  file copy -force $srm_file $dst_map
355  }
356 
357  if {[file exists $srs_file]} {
358  Msg Info "Copying srs file $srs_file into $dst_srs..."
359  file copy -force $srs_file $dst_srs
360  }
361 
362  if {[file exists $srr_file]} {
363  Msg Info "Copying srr file $srr_file into $dst_srr..."
364  file copy -force $srr_file $dst_srr
365  }
366 
367 
368  Msg Info "Copying synth txt files $stxt_files into $dst_rpt..."
369  file copy -force {*}$stxt_files $dst_rpt
370  Msg Info "Copying synth csv files $scsv_files into $dst_rpt..."
371  file copy -force {*}$scsv_files $dst_rpt
372  Msg Info "Copying synth log files $slog_files into $dst_rpt..."
373  file copy -force {*}$slog_files $dst_rpt
374  Msg Info "Copying synth rpt files $srpt_files into $dst_rpt..."
375  file copy -force {*}$srpt_files $dst_rpt
376 
377  Msg Info "Copying impl txt files $dtxt_files into $dst_rpt..."
378  file copy -force {*}$dtxt_files $dst_rpt
379  Msg Info "Copying impl csv files $dcsv_files into $dst_rpt..."
380  file copy -force {*}$dcsv_files $dst_rpt
381  Msg Info "Copying impl log files $dlog_files into $dst_rpt..."
382  file copy -force {*}$dlog_files $dst_rpt
383  Msg Info "Copying impl rpt files $drpt_files into $dst_rpt..."
384  file copy -force {*}$drpt_files $dst_rpt
385 } elseif {[IsDiamond]} {
386  set dst_main [file normalize "$dst_dir/$proj_name\-$describe.bit"]
387  Msg Info "Copying main binary file $main_file.bit into $dst_main..."
388  file copy -force $main_file.bit $dst_main
389  Msg Info "Copying binary generation log $main_file.bgn into $dst_dir/reports..."
390  file copy -force $main_file.bgn $dst_dir/reports
391 } else {
392  Msg CriticalWarning "Firmware binary file not found."
393 }
394 
395 
396 # IPbus XML
397 if {[file exists $xml_dir]} {
398  Msg Info "XML directory found, copying xml files from $xml_dir to $dst_xml..."
399  if {[file exists $dst_xml]} {
400  Msg Info "Directory $dst_xml exists, deleting it..."
401  file delete -force $dst_xml
402  }
403  file copy -force $xml_dir $dst_xml
404 }
405 
406 # Zynq XSA Export
407 if {[IsXilinx]} {
408  # Vivado
409  # automatically export for zynqs (checking via regex)
410  set export_xsa "NONE"
411  set part [get_property part [current_project]]
412 
413  # check for explicit EXPORT_XSA flag in hog.conf
414  set properties [ReadConf [lindex [GetConfFiles $repo_path/Top/$group_name/$proj_name] 0]]
415  if {[dict exists $properties "hog"]} {
416  set propDict [dict get $properties "hog"]
417  if {[dict exists $propDict "EXPORT_XSA"]} {
418  set export_xsa [dict get $propDict "EXPORT_XSA"]
419  }
420  }
421 
422  if {$export_xsa == "NONE"} {
423  set export_xsa false
424  if {([IsZynq $part] || [IsVersal $part])} {
425  Msg Info "SoC FPGA detected (Zynq or Versal), automatically enabling XSA file creation. \
426  To disable it, add 'EXPORT_XSA = false' in the \[hog\] section of hog.conf."
427  set export_xsa true
428  }
429  }
430 
431  if {[string compare [string tolower $export_xsa] "true"] == 0} {
432  set wrote_xsa 0
433 
434  # There is a bug in Vivado 2020.1, check for that version and warn
435  # that we can't export XSAs
436  regexp -- {Vivado v([0-9]{4}\.[0-9,A-z,_,\.]*) } [version] -> VIVADO_VERSION
437  if {[string compare "2020.1" $VIVADO_VERSION] == 0} {
438  Msg Warning "Vivado 2020.1, a patch must be applied to Vivado to export XSA Files, c.f. https://www.xilinx.com/support/answers/75210.html"
439  } else {
440  set dst_xsa [file normalize "$dst_dir/${proj_name}\-$describe.xsa"]
441  Msg Info "Generating XSA File at $dst_xsa"
442 
443  if {[IsVersal $part]} {
444  # Run user pre-platform file
445  set user_pre_platform_file "./Top/$group_name/$proj_name/pre-platform.tcl"
446  if {[file exists $user_pre_platform_file]} {
447  Msg Info "Sourcing user pre-platform file $user_pre_platform_file"
448  source $user_pre_platform_file
449  }
450 
451  # We do not want to touch the full_pdi_file property if there is a _boot .pdi file
452  if {$secondary_file == ""} {
453  set pdi_post_imp [file normalize "$work_path/$top_name.pdi"]
454  set_property platform.full_pdi_file $pdi_post_imp [current_project]
455  Msg Info "XSA file will be generated for Versal with this PDI: $pdi_post_imp"
456  WriteHwPlatformWorkaround "-fixed -force -file {$dst_xsa}"
457  set wrote_xsa 1
458  }
459  Msg Warning "No XSA will be produced in post-bitream for segmented configuration mode. \
460  If you're running with the GUI, please type the following on the Tcl console: write_hw_platform -fixed -force -file $dst_xsa."
461  } else {
462  # We leave include bit also for Versal
463  WriteHwPlatformWorkaround "-include_bit -fixed -force -file {$dst_xsa}"
464  set wrote_xsa 1
465  }
466  }
467 
468  if {$wrote_xsa == 1} {
469  # Determine project type from configuration file
470  set conf_file [lindex [GetConfFiles $repo_path/Top/$group_name/$proj_name] 0]
471  set is_vitis_classic 0
472  set is_vitis_unified 0
473 
474  if {[file exists $conf_file]} {
475  set ide_name_and_ver [GetIDEFromConf $conf_file]
476  set ide_name [string tolower [lindex $ide_name_and_ver 0]]
477  if {[string match "*vitis_classic*" $ide_name] || [string match "*vivado_vitis_classic*" $ide_name]} {
478  set is_vitis_classic 1
479  } elseif {[string match "*vitis_unified*" $ide_name] || [string match "*vivado_vitis_unified*" $ide_name]} {
480  set is_vitis_unified 1
481  }
482  }
483 
484  if {$is_vitis_classic || $is_vitis_unified} {
485  Msg Info "XSA file written to $dst_xsa"
486 
487  set full_proj_name [file join $group_name $proj_name]
488 
489  # Determine command based on project type
490  if {$is_vitis_classic} {
491  set vitis_cmd "xsct $tcl_path/launch.tcl CW -xsa $dst_xsa -vitis_only $full_proj_name"
492  set vitis_type "Vitis Classic"
493  set error_prefix "xsct (vitis classic)"
494  } elseif {$is_vitis_unified} {
495  set vitis_cmd "$tcl_path/launch.tcl CW -xsa $dst_xsa -vitis_only $full_proj_name"
496  set vitis_type "Vitis Unified"
497  set error_prefix "vivado (for vitis unified)"
498  } else {
499  Msg Error "No Vitis project type found."
500  return
501  }
502 
503  Msg Info "Running $vitis_type to create elf file with cmd: $vitis_cmd"
504  set ret [catch {exec -ignorestderr {*}$vitis_cmd >@ stdout} result]
505  if {$ret != 0} {
506  Msg Error "$error_prefix returned an error state."
507  }
508 
509  # Copy ELF files from Vitis build output into bin directory
510  # Extract app names preserving original case from hog.conf,
511  # since Vitis creates directories matching the original case
512  set app_names [list]
513  foreach prop_key [dict keys $properties] {
514  if {[regexp {^app:(.+)$} $prop_key -> raw_app_name]} {
515  lappend app_names [string trim $raw_app_name]
516  }
517  }
518  foreach app_name $app_names {
519  if {$is_vitis_unified} {
520  set elf_src [file normalize "$repo_path/Projects/$full_proj_name/vitis_unified/$app_name/build/$app_name.elf"]
521  } else {
522  set elf_src [file normalize "$repo_path/Projects/$full_proj_name/vitis_classic/$app_name/Release/$app_name.elf"]
523  }
524  set elf_dst [file normalize "$dst_dir/${proj_name}\-${app_name}\-$describe.elf"]
525  if {[file exists $elf_src]} {
526  Msg Info "Copying ELF $elf_src into $elf_dst..."
527  file copy -force $elf_src $elf_dst
528  } else {
529  Msg Warning "ELF file not found: $elf_src"
530  }
531  }
532 
533  # Process ELF files and update bitstream with memory content
534  set mmi_file [file normalize "$dst_dir/${proj_name}\-$describe.mmi"]
535  GenerateBootArtifacts $properties $repo_path $proj_dir $dst_dir $proj_name $describe $dst_main $mmi_file
536  }
537  }
538 
539  }
540 }
541 
542 
543 # Run user post-bitstream file
544 set user_post_bitstream_file "./Top/$group_name/$proj_name/post-bitstream.tcl"
545 if {[file exists $user_post_bitstream_file]} {
546  Msg Info "Sourcing user post-bitstream file $user_post_bitstream_file"
547  source $user_post_bitstream_file
548 }
549 
550 cd $old_path
551 Msg Info "All done."